Dumped on 2012-10-09

Index of database - postbooks_empty


Schema api


View: api.account

Account

api.account Structure
F-Key Name Type Description
account_number character varying
parent_account text
account_name text
active boolean
type text
primary_contact_number text
primary_contact_honorific text
primary_contact_first text
primary_contact_middle text
primary_contact_last text
primary_contact_suffix text
primary_contact_job_title text
primary_contact_voice text
primary_contact_fax text
primary_contact_email text
primary_contact_change text
primary_contact_address_number text
primary_contact_address1 text
primary_contact_address2 text
primary_contact_address3 text
primary_contact_city text
primary_contact_state text
primary_contact_postalcode text
primary_contact_country text
primary_contact_address_change text
secondary_contact_number text
secondary_contact_honorific text
secondary_contact_first text
secondary_contact_middle text
secondary_contact_last text
secondary_contact_suffix text
secondary_contact_job_title text
secondary_contact_voice text
secondary_contact_fax text
secondary_contact_email text
secondary_contact_web text
secondary_contact_change text
secondary_contact_address_number text
secondary_contact_address1 text
secondary_contact_address2 text
secondary_contact_address3 text
secondary_contact_city text
secondary_contact_state text
secondary_contact_postalcode text
secondary_contact_country text
secondary_contact_address_change text
notes text
SELECT (c.crmacct_number)::character varying AS account_number
, p.crmacct_number AS parent_account
, c.crmacct_name AS account_name
, c.crmacct_active AS active
, CASE WHEN 
(c.crmacct_type = 'O'::bpchar) THEN 'Organization'::text ELSE 'Individual'::text END AS type
, pc.cntct_number AS primary_contact_number
, pc.cntct_honorific AS primary_contact_honorific
, pc.cntct_first_name AS primary_contact_first
, pc.cntct_middle AS primary_contact_middle
, pc.cntct_last_name AS primary_contact_last
, pc.cntct_suffix AS primary_contact_suffix
, pc.cntct_title AS primary_contact_job_title
, pc.cntct_phone AS primary_contact_voice
, pc.cntct_fax AS primary_contact_fax
, pc.cntct_email AS primary_contact_email
,''::text AS primary_contact_change
, m.addr_number AS primary_contact_address_number
, m.addr_line1 AS primary_contact_address1
, m.addr_line2 AS primary_contact_address2
, m.addr_line3 AS primary_contact_address3
, m.addr_city AS primary_contact_city
, m.addr_state AS primary_contact_state
, m.addr_postalcode AS primary_contact_postalcode
, m.addr_country AS primary_contact_country
,''::text AS primary_contact_address_change
, sc.cntct_number AS secondary_contact_number
, sc.cntct_honorific AS secondary_contact_honorific
, sc.cntct_first_name AS secondary_contact_first
, sc.cntct_middle AS secondary_contact_middle
, sc.cntct_last_name AS secondary_contact_last
, sc.cntct_suffix AS secondary_contact_suffix
, sc.cntct_title AS secondary_contact_job_title
, sc.cntct_phone AS secondary_contact_voice
, sc.cntct_fax AS secondary_contact_fax
, sc.cntct_email AS secondary_contact_email
, sc.cntct_webaddr AS secondary_contact_web
,''::text AS secondary_contact_change
, s.addr_number AS secondary_contact_address_number
, s.addr_line1 AS secondary_contact_address1
, s.addr_line2 AS secondary_contact_address2
, s.addr_line3 AS secondary_contact_address3
, s.addr_city AS secondary_contact_city
, s.addr_state AS secondary_contact_state
, s.addr_postalcode AS secondary_contact_postalcode
, s.addr_country AS secondary_contact_country
,''::text AS secondary_contact_address_change
, c.crmacct_notes AS notes 
FROM (
     (
           (
                 (
                       (crmacct c 
                     LEFT JOIN crmacct p 
                            ON (
                                   (c.crmacct_id = p.crmacct_parent_id)
                             )
                       )
               LEFT JOIN cntct pc 
                      ON (
                             (c.crmacct_cntct_id_1 = pc.cntct_id)
                       )
                 )
         LEFT JOIN addr m 
                ON (
                       (pc.cntct_addr_id = m.addr_id)
                 )
           )
   LEFT JOIN cntct sc 
          ON (
                 (c.crmacct_cntct_id_2 = sc.cntct_id)
           )
     )
LEFT JOIN addr s 
    ON (
           (sc.cntct_addr_id = s.addr_id)
     )
);

Index - Schema api


View: api.accountchar

Account Characteristics

api.accountchar Structure
F-Key Name Type Description
account_number character varying
characteristic character varying
value text
SELECT (crmacct.crmacct_number)::character varying AS account_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM crmacct
,"char"
, charass 
WHERE (
     (
           ('CRMACCT'::text = charass.charass_target_type)
         AND (crmacct.crmacct_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.accountcomment

Account Comment

api.accountcomment Structure
F-Key Name Type Description
account_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (crmacct.crmacct_number)::character varying AS account_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM crmacct
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'CRMA'::text)
         AND (comment.comment_source_id = crmacct.crmacct_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.accountfile

Account File

api.accountfile Structure
F-Key Name Type Description
account_number text
title text
url text
SELECT crmacct.crmacct_number AS account_number
, url.url_title AS title
, url.url_url AS url 
FROM crmacct
, url 
WHERE (
     (crmacct.crmacct_id = url.url_source_id)
   AND (url.url_source = 'CRMA'::text)
);

Index - Schema api


View: api.accountimage

Account Image

api.accountimage Structure
F-Key Name Type Description
account_number text
image_name text
SELECT crmacct.crmacct_number AS account_number
, image.image_name 
FROM crmacct
, imageass
, image 
WHERE (
     (
           (crmacct.crmacct_id = imageass.imageass_source_id)
         AND (imageass.imageass_source = 'CRMA'::text)
     )
   AND (imageass.imageass_image_id = image.image_id)
);

Index - Schema api


View: api.address

Address

api.address Structure
F-Key Name Type Description
address_number character varying
address1 text
address2 text
address3 text
city text
state text
postal_code text
country text
active boolean
notes text
change text
SELECT (addr.addr_number)::character varying AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postal_code
, addr.addr_country AS country
, addr.addr_active AS active
, addr.addr_notes AS notes
,''::text AS change 
FROM addr;

Index - Schema api


View: api.addresschar

Address Characteristics

api.addresschar Structure
F-Key Name Type Description
address_number character varying
characteristic character varying
value text
SELECT (addr.addr_number)::character varying AS address_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM addr
,"char"
, charass 
WHERE (
     (
           ('ADDR'::text = charass.charass_target_type)
         AND (addr.addr_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.addresscomment

Address Comment

api.addresscomment Structure
F-Key Name Type Description
address_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (addr.addr_number)::character varying AS address_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM addr
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'ADDR'::text)
         AND (comment.comment_source_id = addr.addr_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.apmemo

A/P Credit and Debit Memo

api.apmemo Structure
F-Key Name Type Description
vendor_number text
document_date date
due_date date
document_type text
document_number text
po_number text
journal_number integer
terms text
currency character varying(3)
amount numeric(20,2)
paid numeric(20,2)
balance numeric
notes text
alternate_prepaid_account text
SELECT vendinfo.vend_number AS vendor_number
, apopen.apopen_docdate AS document_date
, apopen.apopen_duedate AS due_date
, CASE WHEN 
(apopen.apopen_doctype = 'C'::bpchar) THEN 'Credit Memo'::text ELSE 'Debit Memo'::text END AS document_type
, apopen.apopen_docnumber AS document_number
, apopen.apopen_ponumber AS po_number
, apopen.apopen_journalnumber AS journal_number
, terms.terms_code AS terms
, curr.curr_abbr AS currency
, apopen.apopen_amount AS amount
, apopen.apopen_paid AS paid
, (apopen.apopen_amount - apopen.apopen_paid) AS balance
, apopen.apopen_notes AS notes
, CASE WHEN 
(apopen.apopen_accnt_id = 
     (-1)
) THEN NULL::text ELSE formatglaccount
(apopen.apopen_accnt_id) END AS alternate_prepaid_account 
FROM (
     (
           (apopen 
         LEFT JOIN vendinfo 
                ON (
                       (vendinfo.vend_id = apopen.apopen_vend_id)
                 )
           )
   LEFT JOIN curr_symbol curr 
          ON (
                 (curr.curr_id = apopen.apopen_curr_id)
           )
     )
LEFT JOIN terms 
    ON (
           (terms.terms_id = apopen.apopen_terms_id)
     )
)
WHERE (apopen.apopen_doctype = ANY 
     (ARRAY['C'::bpchar
           ,'D'::bpchar]
     )
);

Index - Schema api


View: api.armemo

A/R Credit and Debit Memo

api.armemo Structure
F-Key Name Type Description
customer_number text
document_date date
due_date date
document_type text
document_number text
order_number text
journal_number integer
reason_code text
terms text
sales_rep text
currency character varying(3)
amount numeric(20,2)
paid numeric(20,2)
balance numeric
commission_due numeric(20,2)
commission_paid boolean
notes text
alternate_prepaid_sales_category text
alternate_prepaid_account text
SELECT custinfo.cust_number AS customer_number
, aropen.aropen_docdate AS document_date
, aropen.aropen_duedate AS due_date
, CASE WHEN 
(aropen.aropen_doctype = 'C'::bpchar) THEN 'Credit Memo'::text ELSE 'Debit Memo'::text END AS document_type
, aropen.aropen_docnumber AS document_number
, aropen.aropen_applyto AS order_number
, aropen.aropen_journalnumber AS journal_number
, rsncode.rsncode_code AS reason_code
, terms.terms_code AS terms
, salesrep.salesrep_number AS sales_rep
, curr.curr_abbr AS currency
, aropen.aropen_amount AS amount
, aropen.aropen_paid AS paid
, (aropen.aropen_amount - aropen.aropen_paid) AS balance
, aropen.aropen_commission_due AS commission_due
, aropen.aropen_commission_paid AS commission_paid
, aropen.aropen_notes AS notes
, salescat.salescat_name AS alternate_prepaid_sales_category
, CASE WHEN 
(aropen.aropen_accnt_id = 
     (-1)
) THEN NULL::text ELSE formatglaccount
(aropen.aropen_accnt_id) END AS alternate_prepaid_account 
FROM (
     (
           (
                 (
                       (
                             (aropen 
                           LEFT JOIN custinfo 
                                  ON (
                                         (custinfo.cust_id = aropen.aropen_cust_id)
                                   )
                             )
                     LEFT JOIN curr_symbol curr 
                            ON (
                                   (curr.curr_id = aropen.aropen_curr_id)
                             )
                       )
               LEFT JOIN salesrep 
                      ON (
                             (salesrep.salesrep_id = aropen.aropen_salesrep_id)
                       )
                 )
         LEFT JOIN terms 
                ON (
                       (terms.terms_id = aropen.aropen_terms_id)
                 )
           )
   LEFT JOIN salescat 
          ON (
                 (salescat.salescat_id = aropen.aropen_salescat_id)
           )
     )
LEFT JOIN rsncode 
    ON (
           (rsncode.rsncode_id = aropen.aropen_rsncode_id)
     )
)
WHERE (aropen.aropen_doctype = ANY 
     (ARRAY['C'::bpchar
           ,'D'::bpchar]
     )
);

Index - Schema api


View: api.bom

Bill of Material Header

api.bom Structure
F-Key Name Type Description
item_number character varying
revision character varying
document_number text
revision_date date
batch_size numeric(18,6)
total_qty_per numeric(20,8)
SELECT (item.item_number)::character varying AS item_number
, (bomhead.bomhead_revision)::character varying AS revision
, bomhead.bomhead_docnum AS document_number
, bomhead.bomhead_revisiondate AS revision_date
, bomhead.bomhead_batchsize AS batch_size
, bomhead.bomhead_requiredqtyper AS total_qty_per 
FROM bomhead
, item 
WHERE (bomhead.bomhead_item_id = item.item_id);

Index - Schema api


View: api.bomitem

Bill of Material Item

api.bomitem Structure
F-Key Name Type Description
id integer
bom_item_number character varying
bom_revision character varying
sequence_number integer
item_number text
effective text
expires text
qty_per numeric(20,8)
issue_uom text
scrap numeric(8,4)
create_child_wo boolean
issue_method text
used_at text
schedule_at_wo_operation boolean
ecn_number text
notes text
reference text
substitutions text
characteristic text
value text
SELECT bomitem.bomitem_id AS id
, (p.item_number)::character varying AS bom_item_number
, (bomhead.bomhead_revision)::character varying AS bom_revision
, bomitem.bomitem_seqnumber AS sequence_number
, i.item_number
, CASE WHEN 
(bomitem.bomitem_effective = startoftime
     ()
) THEN 'Always'::text ELSE formatdate
(bomitem.bomitem_effective) END AS effective
, CASE WHEN 
(bomitem.bomitem_expires = endoftime
     ()
) THEN 'Never'::text ELSE formatdate
(bomitem.bomitem_expires) END AS expires
, bomitem.bomitem_qtyper AS qty_per
, uom.uom_name AS issue_uom
, bomitem.bomitem_scrap AS scrap
, bomitem.bomitem_createwo AS create_child_wo
, CASE WHEN 
(bomitem.bomitem_issuemethod = 'M'::bpchar) THEN 'Mixed'::text WHEN 
(bomitem.bomitem_issuemethod = 'L'::bpchar) THEN 'Pull'::text WHEN 
(bomitem.bomitem_issuemethod = 'S'::bpchar) THEN 'Push'::text ELSE NULL::text END AS issue_method
, formatbooseq
(p.item_id
     , bomitem.bomitem_booitem_seq_id
) AS used_at
, bomitem.bomitem_schedatwooper AS schedule_at_wo_operation
, bomitem.bomitem_ecn AS ecn_number
, bomitem.bomitem_notes AS notes
, bomitem.bomitem_ref AS reference
, CASE WHEN 
(bomitem.bomitem_subtype = 'N'::bpchar) THEN 'No'::text WHEN 
(bomitem.bomitem_subtype = 'I'::bpchar) THEN 'Item-Defined'::text WHEN 
(bomitem.bomitem_subtype = 'B'::bpchar) THEN 'BOM-Defined'::text ELSE NULL::text END AS substitutions
,"char".char_name AS characteristic
, bomitem.bomitem_value AS value 
FROM (
     (bomitem 
   LEFT JOIN bomhead 
          ON (
                 (
                       (bomitem.bomitem_parent_item_id = bomhead.bomhead_item_id)
                     AND (bomitem.bomitem_rev_id = bomhead.bomhead_rev_id)
                 )
           )
     )
LEFT JOIN"char"
    ON (
           (bomitem.bomitem_char_id = "char".char_id)
     )
)
, item p
, item i
, uom 
WHERE (
     (
           (bomitem.bomitem_parent_item_id = p.item_id)
         AND (bomitem.bomitem_item_id = i.item_id)
     )
   AND (bomitem.bomitem_uom_id = uom.uom_id)
)
ORDER BY p.item_number
, bomitem.bomitem_seqnumber;

Index - Schema api


View: api.bomitemcomment

Bill of Material Comment

api.bomitemcomment Structure
F-Key Name Type Description
bomitem_id integer
type text
date timestamp with time zone
username text
text text
SELECT bomitem.bomitem_id
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM (bomitem 
LEFT JOIN bomhead 
    ON (
           (
                 (bomitem.bomitem_parent_item_id = bomhead.bomhead_item_id)
               AND (bomitem.bomitem_rev_id = bomhead.bomhead_rev_id)
           )
     )
)
, item
, cmnttype
, comment 
WHERE (
     (
           (
                 (comment.comment_source = 'BMI'::text)
               AND (comment.comment_source_id = bomitem.bomitem_id)
           )
         AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
     )
   AND (bomitem.bomitem_parent_item_id = item.item_id)
)
ORDER BY item.item_number
, bomhead.bomhead_revision
, bomitem.bomitem_seqnumber
, comment.comment_date;

Index - Schema api


View: api.bomitemsubstitute

Bill of Material Item Substitute

api.bomitemsubstitute Structure
F-Key Name Type Description
bomitem_id integer
bom_item_number character varying
bom_revision character varying
sequence_number integer
substitute_item_number character varying
sub_parent_uom_ratio numeric(20,10)
ranking integer
SELECT bomitem.bomitem_id
, (p.item_number)::character varying AS bom_item_number
, (bomhead.bomhead_revision)::character varying AS bom_revision
, bomitem.bomitem_seqnumber AS sequence_number
, (s.item_number)::character varying AS substitute_item_number
, bomitemsub.bomitemsub_uomratio AS sub_parent_uom_ratio
, bomitemsub.bomitemsub_rank AS ranking 
FROM item p
, item s
, (bomitem 
LEFT JOIN bomhead 
    ON (
           (
                 (bomitem.bomitem_parent_item_id = bomhead.bomhead_item_id)
               AND (bomitem.bomitem_rev_id = bomhead.bomhead_rev_id)
           )
     )
)
, bomitemsub 
WHERE (
     (
           (p.item_id = bomitem.bomitem_parent_item_id)
         AND (s.item_id = bomitemsub.bomitemsub_item_id)
     )
   AND (bomitemsub.bomitemsub_bomitem_id = bomitem.bomitem_id)
);

Index - Schema api


View: api.budget

Budget Header

api.budget Structure
F-Key Name Type Description
name text
description text
SELECT budghead.budghead_name AS name
, budghead.budghead_descrip AS description 
FROM budghead 
ORDER BY budghead.budghead_name;

Index - Schema api


View: api.budgetentry

Budget Entry

api.budgetentry Structure
F-Key Name Type Description
name text
account text
period_start date
amount numeric(20,4)
SELECT budghead.budghead_name AS name
, formatglaccount
(accnt.accnt_id) AS account
, period.period_start
, budgitem.budgitem_amount AS amount 
FROM budgitem
, budghead
, period
, accnt 
WHERE (
     (
           (budgitem.budgitem_budghead_id = budghead.budghead_id)
         AND (budgitem.budgitem_period_id = period.period_id)
     )
   AND (budgitem.budgitem_accnt_id = accnt.accnt_id)
)
ORDER BY budghead.budghead_name
, period.period_start
, formatglaccount
(accnt.accnt_id);

Index - Schema api


View: api.cashreceipt

This view can be used as an interface to import Cash Receipt data directly into the system. Required fields will be checked and default values will be populated

api.cashreceipt Structure
F-Key Name Type Description
customer_number character varying
funds_type character varying
check_document_number character varying
customer_name text
customer_address text
currency character varying(3)
amount_received numeric(20,2)
post_to text
distribution_date text
apply_balance_as text
sales_category text
notes text
SELECT (custinfo.cust_number)::character varying AS customer_number
, CASE WHEN 
(cashrcpt.cashrcpt_fundstype = 'C'::bpchar) THEN 'Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'T'::bpchar) THEN 'Certified Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'M'::bpchar) THEN 'Master Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'V'::bpchar) THEN 'Visa'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'A'::bpchar) THEN 'American Express'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'D'::bpchar) THEN 'Discover Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'R'::bpchar) THEN 'Other Credit Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'K'::bpchar) THEN 'Cash'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'W'::bpchar) THEN 'Wire Transfer'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'O'::bpchar) THEN 'Other'::character varying ELSE NULL::character varying END AS funds_type
, (cashrcpt.cashrcpt_docnumber)::character varying AS check_document_number
, custinfo.cust_name AS customer_name
, m.addr_line1 AS customer_address
, curr_symbol.curr_abbr AS currency
, cashrcpt.cashrcpt_amount AS amount_received
, bankaccnt.bankaccnt_name AS post_to
, formatdate
(cashrcpt.cashrcpt_distdate) AS distribution_date
, CASE WHEN cashrcpt.cashrcpt_usecustdeposit THEN 'Customer Deposit'::text ELSE 'Credit Memo'::text END AS apply_balance_as
, salescat.salescat_name AS sales_category
, cashrcpt.cashrcpt_notes AS notes 
FROM (
     (
           (
                 (
                       (
                             (cashrcpt 
                           LEFT JOIN custinfo 
                                  ON (
                                         (custinfo.cust_id = cashrcpt.cashrcpt_cust_id)
                                   )
                             )
                     LEFT JOIN cntct mc 
                            ON (
                                   (custinfo.cust_cntct_id = mc.cntct_id)
                             )
                       )
               LEFT JOIN addr m 
                      ON (
                             (mc.cntct_addr_id = m.addr_id)
                       )
                 )
         LEFT JOIN curr_symbol 
                ON (
                       (curr_symbol.curr_id = cashrcpt.cashrcpt_curr_id)
                 )
           )
   LEFT JOIN bankaccnt 
          ON (
                 (bankaccnt.bankaccnt_id = cashrcpt.cashrcpt_bankaccnt_id)
           )
     )
LEFT JOIN salescat 
    ON (
           (salescat.salescat_id = cashrcpt.cashrcpt_salescat_id)
     )
);

Index - Schema api


View: api.cashreceiptapply

This view can be used as an interface to import Cash Receipt Application data directly into the system. Required fields will be checked and default values will be populated

api.cashreceiptapply Structure
F-Key Name Type Description
customer_number character varying
funds_type character varying
check_document_number character varying
doc_type character varying
doc_number character varying
customer_name text
customer_address text
doc_date text
due_date text
currency character varying(3)
open_amount numeric(20,2)
amount_to_apply numeric(20,2)
cashrcptitem_discount numeric(20,2)
SELECT (custinfo.cust_number)::character varying AS customer_number
, CASE WHEN 
(cashrcpt.cashrcpt_fundstype = 'C'::bpchar) THEN 'Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'T'::bpchar) THEN 'Certified Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'M'::bpchar) THEN 'Master Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'V'::bpchar) THEN 'Visa'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'A'::bpchar) THEN 'American Express'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'D'::bpchar) THEN 'Discover Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'R'::bpchar) THEN 'Other Credit Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'K'::bpchar) THEN 'Cash'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'W'::bpchar) THEN 'Wire Transfer'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'O'::bpchar) THEN 'Other'::character varying ELSE NULL::character varying END AS funds_type
, (cashrcpt.cashrcpt_docnumber)::character varying AS check_document_number
, (aropen.aropen_doctype)::character varying AS doc_type
, (aropen.aropen_docnumber)::character varying AS doc_number
, custinfo.cust_name AS customer_name
, m.addr_line1 AS customer_address
, formatdate
(aropen.aropen_docdate) AS doc_date
, formatdate
(aropen.aropen_duedate) AS due_date
, curr_symbol.curr_abbr AS currency
, aropen.aropen_amount AS open_amount
, cashrcptitem.cashrcptitem_amount AS amount_to_apply
, cashrcptitem.cashrcptitem_discount 
FROM (
     (
           (
                 (
                       (
                             (cashrcptitem 
                           LEFT JOIN cashrcpt 
                                  ON (
                                         (cashrcpt.cashrcpt_id = cashrcptitem.cashrcptitem_cashrcpt_id)
                                   )
                             )
                     LEFT JOIN custinfo 
                            ON (
                                   (custinfo.cust_id = cashrcpt.cashrcpt_cust_id)
                             )
                       )
               LEFT JOIN cntct mc 
                      ON (
                             (custinfo.cust_cntct_id = mc.cntct_id)
                       )
                 )
         LEFT JOIN addr m 
                ON (
                       (mc.cntct_addr_id = m.addr_id)
                 )
           )
   LEFT JOIN curr_symbol 
          ON (
                 (curr_symbol.curr_id = cashrcpt.cashrcpt_curr_id)
           )
     )
LEFT JOIN aropen 
    ON (
           (aropen.aropen_id = cashrcptitem.cashrcptitem_aropen_id)
     )
);

Index - Schema api


View: api.cashreceiptapplymisc

This view can be used as an interface to import Cash Receipt Miscellaneous Application data directly into the system. Required fields will be checked and default values will be populated

api.cashreceiptapplymisc Structure
F-Key Name Type Description
customer_number character varying
funds_type character varying
check_document_number character varying
account character varying
customer_name text
customer_address text
account_description text
currency character varying(3)
amount_to_distribute numeric(20,2)
notes text
SELECT (custinfo.cust_number)::character varying AS customer_number
, CASE WHEN 
(cashrcpt.cashrcpt_fundstype = 'C'::bpchar) THEN 'Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'T'::bpchar) THEN 'Certified Check'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'M'::bpchar) THEN 'Master Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'V'::bpchar) THEN 'Visa'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'A'::bpchar) THEN 'American Express'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'D'::bpchar) THEN 'Discover Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'R'::bpchar) THEN 'Other Credit Card'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'K'::bpchar) THEN 'Cash'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'W'::bpchar) THEN 'Wire Transfer'::character varying WHEN 
(cashrcpt.cashrcpt_fundstype = 'O'::bpchar) THEN 'Other'::character varying ELSE NULL::character varying END AS funds_type
, (cashrcpt.cashrcpt_docnumber)::character varying AS check_document_number
, (formatglaccount
     (accnt.accnt_id)
)::character varying AS account
, custinfo.cust_name AS customer_name
, m.addr_line1 AS customer_address
, accnt.accnt_descrip AS account_description
, curr_symbol.curr_abbr AS currency
, cashrcptmisc.cashrcptmisc_amount AS amount_to_distribute
, cashrcptmisc.cashrcptmisc_notes AS notes 
FROM (
     (
           (
                 (
                       (
                             (cashrcptmisc 
                           LEFT JOIN cashrcpt 
                                  ON (
                                         (cashrcpt.cashrcpt_id = cashrcptmisc.cashrcptmisc_cashrcpt_id)
                                   )
                             )
                     LEFT JOIN custinfo 
                            ON (
                                   (custinfo.cust_id = cashrcpt.cashrcpt_cust_id)
                             )
                       )
               LEFT JOIN cntct mc 
                      ON (
                             (custinfo.cust_cntct_id = mc.cntct_id)
                       )
                 )
         LEFT JOIN addr m 
                ON (
                       (mc.cntct_addr_id = m.addr_id)
                 )
           )
   LEFT JOIN curr_symbol 
          ON (
                 (curr_symbol.curr_id = cashrcpt.cashrcpt_curr_id)
           )
     )
LEFT JOIN accnt 
    ON (
           (accnt.accnt_id = cashrcptmisc.cashrcptmisc_accnt_id)
     )
);

Index - Schema api


View: api.contact

Contact

api.contact Structure
F-Key Name Type Description
contact_number character varying
honorific text
first text
middle text
last text
suffix text
initials text
crm_account text
active boolean
job_title text
voice text
alternate text
fax text
email text
web text
contact_change text
address_number text
address1 text
address2 text
address3 text
city text
state text
postal_code text
country text
notes text
address_change text
SELECT (cntct.cntct_number)::character varying AS contact_number
, cntct.cntct_honorific AS honorific
, cntct.cntct_first_name AS first
, cntct.cntct_middle AS middle
, cntct.cntct_last_name AS last
, cntct.cntct_suffix AS suffix
, cntct.cntct_initials AS initials
, crmacct.crmacct_number AS crm_account
, cntct.cntct_active AS active
, cntct.cntct_title AS job_title
, cntct.cntct_phone AS voice
, cntct.cntct_phone2 AS alternate
, cntct.cntct_fax AS fax
, cntct.cntct_email AS email
, cntct.cntct_webaddr AS web
,''::text AS contact_change
, addr.addr_number AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postal_code
, addr.addr_country AS country
, cntct.cntct_notes AS notes
,''::text AS address_change 
FROM (
     (cntct 
   LEFT JOIN addr 
          ON (
                 (cntct.cntct_addr_id = addr.addr_id)
           )
     )
LEFT JOIN crmacct 
    ON (
           (cntct.cntct_crmacct_id = crmacct.crmacct_id)
     )
);

Index - Schema api


View: api.contactchar

Contact Characteristics

api.contactchar Structure
F-Key Name Type Description
contact_number text
characteristic character varying
value text
SELECT cntct.cntct_number AS contact_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM cntct
,"char"
, charass 
WHERE (
     (
           ('CNTCT'::text = charass.charass_target_type)
         AND (cntct.cntct_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.contactcomment

Contact Comment

api.contactcomment Structure
F-Key Name Type Description
contact_number text
type text
date timestamp with time zone
username text
text text
SELECT cntct.cntct_number AS contact_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM cntct
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'T'::text)
         AND (comment.comment_source_id = cntct.cntct_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.creditmemo

Credit Memo Header

api.creditmemo Structure
F-Key Name Type Description
memo_number text
apply_to text
memo_date date
status text
sales_rep text
commission numeric(8,4)
tax_zone text
reason_code text
on_hold boolean
customer_number text
billto_name text
billto_address1 text
billto_address2 text
billto_address3 text
billto_city text
billto_state text
billto_postal_code text
billto_country text
shipto_number text
shipto_name text
shipto_address1 text
shipto_address2 text
shipto_address3 text
shipto_city text
shipto_state text
shipto_postal_code text
shipto_country text
customer_po_number text
notes text
currency character varying(3)
misc_charge_description text
misc_charge_amount numeric(16,4)
misc_charge_credit_account text
freight numeric(16,4)
SELECT cmhead.cmhead_number AS memo_number
, CASE WHEN 
(cmhead.cmhead_invcnumber = '-1'::text) THEN ''::text ELSE cmhead.cmhead_invcnumber END AS apply_to
, cmhead.cmhead_docdate AS memo_date
, CASE WHEN cmhead.cmhead_posted THEN 'Posted'::text ELSE 'Unposted'::text END AS status
, salesrep.salesrep_number AS sales_rep
, cmhead.cmhead_commission AS commission
, COALESCE
(taxzone.taxzone_code
     ,'None'::text
) AS tax_zone
, COALESCE
(rsncode.rsncode_code
     ,'None'::text
) AS reason_code
, cmhead.cmhead_hold AS on_hold
, custinfo.cust_number AS customer_number
, cmhead.cmhead_billtoname AS billto_name
, cmhead.cmhead_billtoaddress1 AS billto_address1
, cmhead.cmhead_billtoaddress2 AS billto_address2
, cmhead.cmhead_billtoaddress3 AS billto_address3
, cmhead.cmhead_billtocity AS billto_city
, cmhead.cmhead_billtostate AS billto_state
, cmhead.cmhead_billtozip AS billto_postal_code
, cmhead.cmhead_billtocountry AS billto_country
, shiptoinfo.shipto_num AS shipto_number
, cmhead.cmhead_shipto_name AS shipto_name
, cmhead.cmhead_shipto_address1 AS shipto_address1
, cmhead.cmhead_shipto_address2 AS shipto_address2
, cmhead.cmhead_shipto_address3 AS shipto_address3
, cmhead.cmhead_shipto_city AS shipto_city
, cmhead.cmhead_shipto_state AS shipto_state
, cmhead.cmhead_shipto_zipcode AS shipto_postal_code
, cmhead.cmhead_shipto_country AS shipto_country
, cmhead.cmhead_custponumber AS customer_po_number
, cmhead.cmhead_comments AS notes
, curr.curr_abbr AS currency
, cmhead.cmhead_misc_descrip AS misc_charge_description
, cmhead.cmhead_misc AS misc_charge_amount
, CASE WHEN 
(cmhead.cmhead_misc_accnt_id = 
     (-1)
) THEN ''::text ELSE formatglaccount
(cmhead.cmhead_misc_accnt_id) END AS misc_charge_credit_account
, cmhead.cmhead_freight AS freight 
FROM (
     (
           (
                 (
                       (
                             (cmhead 
                           LEFT JOIN custinfo 
                                  ON (
                                         (custinfo.cust_id = cmhead.cmhead_cust_id)
                                   )
                             )
                     LEFT JOIN shiptoinfo 
                            ON (
                                   (shiptoinfo.shipto_id = cmhead.cmhead_shipto_id)
                             )
                       )
               LEFT JOIN curr_symbol curr 
                      ON (
                             (curr.curr_id = cmhead.cmhead_curr_id)
                       )
                 )
         LEFT JOIN salesrep 
                ON (
                       (salesrep.salesrep_id = cmhead.cmhead_salesrep_id)
                 )
           )
   LEFT JOIN taxzone 
          ON (
                 (taxzone.taxzone_id = cmhead.cmhead_taxzone_id)
           )
     )
LEFT JOIN rsncode 
    ON (
           (rsncode.rsncode_id = cmhead.cmhead_rsncode_id)
     )
);

Index - Schema api


View: api.creditmemoline

Credit Memo Line

api.creditmemoline Structure
F-Key Name Type Description
memo_number text
line_number integer
item_number text
recv_site text
reason_code text
qty_returned numeric(18,6)
qty_to_credit numeric(18,6)
qty_uom text
net_unit_price numeric(16,4)
price_uom text
tax_type text
notes text
SELECT cmhead.cmhead_number AS memo_number
, cmitem.cmitem_linenumber AS line_number
, item.item_number
, whsinfo.warehous_code AS recv_site
, rsncode.rsncode_code AS reason_code
, cmitem.cmitem_qtyreturned AS qty_returned
, cmitem.cmitem_qtycredit AS qty_to_credit
, COALESCE
(qty_uom.uom_name
     ,'None'::text
) AS qty_uom
, cmitem.cmitem_unitprice AS net_unit_price
, COALESCE
(price_uom.uom_name
     ,'None'::text
) AS price_uom
, COALESCE
(taxtype.taxtype_name
     ,'None'::text
) AS tax_type
, cmitem.cmitem_comments AS notes 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (cmitem 
                                       LEFT JOIN cmhead 
                                              ON (
                                                     (cmitem.cmitem_cmhead_id = cmhead.cmhead_id)
                                               )
                                         )
                                 LEFT JOIN itemsite 
                                        ON (
                                               (itemsite.itemsite_id = cmitem.cmitem_itemsite_id)
                                         )
                                   )
                           LEFT JOIN item 
                                  ON (
                                         (item.item_id = itemsite.itemsite_item_id)
                                   )
                             )
                     LEFT JOIN whsinfo 
                            ON (
                                   (whsinfo.warehous_id = itemsite.itemsite_warehous_id)
                             )
                       )
               LEFT JOIN rsncode 
                      ON (
                             (rsncode.rsncode_id = cmitem.cmitem_rsncode_id)
                       )
                 )
         LEFT JOIN taxtype 
                ON (
                       (taxtype.taxtype_id = cmitem.cmitem_taxtype_id)
                 )
           )
   LEFT JOIN uom qty_uom 
          ON (
                 (qty_uom.uom_id = cmitem.cmitem_qty_uom_id)
           )
     )
LEFT JOIN uom price_uom 
    ON (
           (price_uom.uom_id = cmitem.cmitem_price_uom_id)
     )
);

Index - Schema api


View: api.custchar

Customer Characteristics

api.custchar Structure
F-Key Name Type Description
customer_number character varying
characteristic character varying
value text
SELECT (custinfo.cust_number)::character varying AS customer_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM custinfo
,"char"
, charass 
WHERE (
     (
           ('C'::text = charass.charass_target_type)
         AND (custinfo.cust_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.custcomment

Customer Comment

api.custcomment Structure
F-Key Name Type Description
customer_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (custinfo.cust_number)::character varying AS customer_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM custinfo
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'C'::text)
         AND (comment.comment_source_id = custinfo.cust_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.custcreditcard

Customer Credit Cards.

api.custcreditcard Structure
F-Key Name Type Description
customer_number character varying
credit_card_type text
active boolean
credit_card_number bytea
name bytea
street_address1 bytea
street_address2 bytea
city bytea
state bytea
postal_code bytea
country bytea
expiration_month bytea
expiration_year bytea
key text
SELECT (custinfo.cust_number)::character varying AS customer_number
, CASE WHEN 
(ccard.ccard_type = 'V'::bpchar) THEN 'Visa'::text WHEN 
(ccard.ccard_type = 'M'::bpchar) THEN 'Master Card'::text WHEN 
(ccard.ccard_type = 'A'::bpchar) THEN 'American Express'::text WHEN 
(ccard.ccard_type = 'D'::bpchar) THEN 'Discover'::text ELSE 'Not Supported'::text END AS credit_card_type
, ccard.ccard_active AS active
, ccard.ccard_number AS credit_card_number
, ccard.ccard_name AS name
, ccard.ccard_address1 AS street_address1
, ccard.ccard_address2 AS street_address2
, ccard.ccard_city AS city
, ccard.ccard_state AS state
, ccard.ccard_zip AS postal_code
, ccard.ccard_country AS country
, ccard.ccard_month_expired AS expiration_month
, ccard.ccard_year_expired AS expiration_year
,''::text AS key 
FROM ccard
, custinfo 
WHERE (ccard.ccard_cust_id = custinfo.cust_id);

Index - Schema api


View: api.customer

Customer

api.customer Structure
F-Key Name Type Description
customer_number character varying
customer_type text
customer_name text
active boolean
sales_rep text
commission numeric
ship_via text
ship_form text
shipping_charges text
accepts_backorders boolean
accepts_partial_shipments boolean
allow_free_form_shipto boolean
allow_free_form_billto boolean
preferred_selling_site text
default_tax_zone text
default_terms text
balance_method text
default_discount numeric(10,6)
default_currency character varying(3)
credit_limit_currency character varying(3)
credit_limit integer
alternate_grace_days integer
credit_rating text
credit_status text
credit_status_exceed_warn boolean
credit_status_exceed_hold boolean
uses_purchase_orders boolean
uses_blanket_pos boolean
billing_contact_number text
billing_contact_honorific text
billing_contact_first text
billing_contact_middle text
billing_contact_last text
billing_contact_suffix text
billing_contact_job_title text
billing_contact_voice text
billing_contact_alternate text
billing_contact_fax text
billing_contact_email text
billing_contact_web text
billing_contact_change text
billing_contact_address_number text
billing_contact_address1 text
billing_contact_address2 text
billing_contact_address3 text
billing_contact_city text
billing_contact_state text
billing_contact_postalcode text
billing_contact_country text
billing_contact_address_change text
correspond_contact_number text
correspond_contact_honorific text
correspond_contact_first text
correspond_contact_middle text
correspond_contact_last text
correspond_contact_suffix text
correspond_contact_job_title text
correspond_contact_voice text
correspond_contact_alternate text
correspond_contact_fax text
correspond_contact_email text
correspond_contact_web text
correspond_contact_change text
correspond_contact_address_number text
correspond_contact_address1 text
correspond_contact_address2 text
correspond_contact_address3 text
correspond_contact_city text
correspond_contact_state text
correspond_contact_postalcode text
correspond_contact_country text
correspond_contact_address_change text
notes text
SELECT (custinfo.cust_number)::character varying AS customer_number
, custtype.custtype_code AS customer_type
, custinfo.cust_name AS customer_name
, custinfo.cust_active AS active
, salesrep.salesrep_number AS sales_rep
, (custinfo.cust_commprcnt * 
     (100)::numeric
) AS commission
, custinfo.cust_shipvia AS ship_via
, shipform.shipform_name AS ship_form
, shipchrg.shipchrg_name AS shipping_charges
, custinfo.cust_backorder AS accepts_backorders
, custinfo.cust_partialship AS accepts_partial_shipments
, custinfo.cust_ffshipto AS allow_free_form_shipto
, custinfo.cust_ffbillto AS allow_free_form_billto
, whsinfo.warehous_code AS preferred_selling_site
, taxzone.taxzone_code AS default_tax_zone
, terms.terms_code AS default_terms
, CASE WHEN 
(custinfo.cust_balmethod = 'B'::bpchar) THEN 'Balance Forward'::text ELSE 'Open Item'::text END AS balance_method
, custinfo.cust_discntprcnt AS default_discount
, dc.curr_abbr AS default_currency
, clc.curr_abbr AS credit_limit_currency
, custinfo.cust_creditlmt AS credit_limit
, CASE WHEN 
(COALESCE
     (custinfo.cust_gracedays
           , 0
     ) > 0
) THEN custinfo.cust_gracedays ELSE NULL::integer END AS alternate_grace_days
, custinfo.cust_creditrating AS credit_rating
, CASE WHEN 
(custinfo.cust_creditstatus = 'G'::bpchar) THEN 'In Good Standing'::text WHEN 
(custinfo.cust_creditstatus = 'W'::bpchar) THEN 'On Credit Warning'::text ELSE 'On Credit Hold'::text END AS credit_status
, custinfo.cust_autoupdatestatus AS credit_status_exceed_warn
, custinfo.cust_autoholdorders AS credit_status_exceed_hold
, custinfo.cust_usespos AS uses_purchase_orders
, custinfo.cust_blanketpos AS uses_blanket_pos
, mc.cntct_number AS billing_contact_number
, mc.cntct_honorific AS billing_contact_honorific
, mc.cntct_first_name AS billing_contact_first
, mc.cntct_middle AS billing_contact_middle
, mc.cntct_last_name AS billing_contact_last
, mc.cntct_suffix AS billing_contact_suffix
, mc.cntct_title AS billing_contact_job_title
, mc.cntct_phone AS billing_contact_voice
, mc.cntct_phone2 AS billing_contact_alternate
, mc.cntct_fax AS billing_contact_fax
, mc.cntct_email AS billing_contact_email
, mc.cntct_webaddr AS billing_contact_web
,''::text AS billing_contact_change
, m.addr_number AS billing_contact_address_number
, m.addr_line1 AS billing_contact_address1
, m.addr_line2 AS billing_contact_address2
, m.addr_line3 AS billing_contact_address3
, m.addr_city AS billing_contact_city
, m.addr_state AS billing_contact_state
, m.addr_postalcode AS billing_contact_postalcode
, m.addr_country AS billing_contact_country
,''::text AS billing_contact_address_change
, cc.cntct_number AS correspond_contact_number
, cc.cntct_honorific AS correspond_contact_honorific
, cc.cntct_first_name AS correspond_contact_first
, cc.cntct_middle AS correspond_contact_middle
, cc.cntct_last_name AS correspond_contact_last
, cc.cntct_suffix AS correspond_contact_suffix
, cc.cntct_title AS correspond_contact_job_title
, cc.cntct_phone AS correspond_contact_voice
, cc.cntct_phone2 AS correspond_contact_alternate
, cc.cntct_fax AS correspond_contact_fax
, cc.cntct_email AS correspond_contact_email
, cc.cntct_webaddr AS correspond_contact_web
,''::text AS correspond_contact_change
, c.addr_number AS correspond_contact_address_number
, c.addr_line1 AS correspond_contact_address1
, c.addr_line2 AS correspond_contact_address2
, c.addr_line3 AS correspond_contact_address3
, c.addr_city AS correspond_contact_city
, c.addr_state AS correspond_contact_state
, c.addr_postalcode AS correspond_contact_postalcode
, c.addr_country AS correspond_contact_country
,''::text AS correspond_contact_address_change
, custinfo.cust_comments AS notes 
FROM (
     (
           (
                 (
                       (
                             (
                                   (custinfo 
                                 LEFT JOIN shipchrg 
                                        ON (
                                               (custinfo.cust_shipchrg_id = shipchrg.shipchrg_id)
                                         )
                                   )
                           LEFT JOIN whsinfo 
                                  ON (
                                         (custinfo.cust_preferred_warehous_id = whsinfo.warehous_id)
                                   )
                             )
                     LEFT JOIN cntct mc 
                            ON (
                                   (custinfo.cust_cntct_id = mc.cntct_id)
                             )
                       )
               LEFT JOIN addr m 
                      ON (
                             (mc.cntct_addr_id = m.addr_id)
                       )
                 )
         LEFT JOIN cntct cc 
                ON (
                       (custinfo.cust_corrcntct_id = cc.cntct_id)
                 )
           )
   LEFT JOIN addr c 
          ON (
                 (cc.cntct_addr_id = c.addr_id)
           )
     )
LEFT JOIN taxzone 
    ON (
           (custinfo.cust_taxzone_id = taxzone.taxzone_id)
     )
)
, custtype
, salesrep
, shipform
, curr_symbol dc
, curr_symbol clc
, terms 
WHERE (
     (
           (
                 (
                       (
                             (custinfo.cust_custtype_id = custtype.custtype_id)
                           AND (custinfo.cust_salesrep_id = salesrep.salesrep_id)
                       )
                     AND (custinfo.cust_shipform_id = shipform.shipform_id)
                 )
               AND (custinfo.cust_curr_id = dc.curr_id)
           )
         AND (custinfo.cust_creditlmt_curr_id = clc.curr_id)
     )
   AND (custinfo.cust_terms_id = terms.terms_id)
);

Index - Schema api


View: api.customertaxreg

Customer Tax Registrations

api.customertaxreg Structure
F-Key Name Type Description
customer_number character varying
tax_zone character varying
tax_authority character varying
registration_number text
start_date text
end_date text
notes text
SELECT (custinfo.cust_number)::character varying AS customer_number
, (COALESCE
     (taxzone.taxzone_code
           ,'Any'::text
     )
)::character varying AS tax_zone
, (taxauth.taxauth_code)::character varying AS tax_authority
, taxreg.taxreg_number AS registration_number
, CASE WHEN 
(taxreg.taxreg_effective = startoftime
     ()
) THEN 'Always'::text ELSE formatdate
(taxreg.taxreg_effective) END AS start_date
, CASE WHEN 
(taxreg.taxreg_expires = endoftime
     ()
) THEN 'Never'::text ELSE formatdate
(taxreg.taxreg_expires) END AS end_date
, taxreg.taxreg_notes AS notes 
FROM (
     (
           (taxreg 
         LEFT JOIN custinfo 
                ON (
                       (custinfo.cust_id = taxreg.taxreg_rel_id)
                 )
           )
   LEFT JOIN taxauth 
          ON (
                 (taxauth.taxauth_id = taxreg.taxreg_taxauth_id)
           )
     )
LEFT JOIN taxzone 
    ON (
           (taxzone.taxzone_id = taxreg.taxreg_taxzone_id)
     )
)
WHERE (taxreg.taxreg_rel_type = 'C'::bpchar)
ORDER BY custinfo.cust_number
, taxreg.taxreg_number;

Index - Schema api


View: api.customertype

Customer Type

api.customertype Structure
F-Key Name Type Description
code character varying
description text
enable_characteristics_profile boolean
SELECT (custtype.custtype_code)::character varying AS code
, custtype.custtype_descrip AS description
, custtype.custtype_char AS enable_characteristics_profile 
FROM custtype 
ORDER BY custtype.custtype_code;

Index - Schema api


View: api.customertypechar

Customer Type Characteristics

api.customertypechar Structure
F-Key Name Type Description
customer_type character varying
characteristic character varying
value text
is_default boolean
SELECT (custtype.custtype_code)::character varying AS customer_type
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value
, charass.charass_default AS is_default 
FROM custtype
,"char"
, charass 
WHERE (
     (
           ('CT'::text = charass.charass_target_type)
         AND (custtype.custtype_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.custshipto

Customer Shipto Address

api.custshipto Structure
F-Key Name Type Description
customer_number character varying
shipto_number character varying
active boolean
name text
default_flag boolean
address_number text
address1 text
address2 text
address3 text
city text
state text
postal_code text
country text
address_change text
contact_number text
honorific text
first text
middle text
last text
suffix text
job_title text
phone text
fax text
email text
contact_change text
sales_rep text
commission numeric
zone text
tax_zone text
ship_via text
ship_form text
shipping_charges text
edi_profile text
general_notes text
shipping_notes text
SELECT (custinfo.cust_number)::character varying AS customer_number
, (shiptoinfo.shipto_num)::character varying AS shipto_number
, shiptoinfo.shipto_active AS active
, shiptoinfo.shipto_name AS name
, shiptoinfo.shipto_default AS default_flag
, addr.addr_number AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postal_code
, addr.addr_country AS country
,''::text AS address_change
, cntct.cntct_number AS contact_number
, cntct.cntct_honorific AS honorific
, cntct.cntct_first_name AS first
, cntct.cntct_middle AS middle
, cntct.cntct_last_name AS last
, cntct.cntct_suffix AS suffix
, cntct.cntct_title AS job_title
, cntct.cntct_phone AS phone
, cntct.cntct_fax AS fax
, cntct.cntct_email AS email
,''::text AS contact_change
, salesrep.salesrep_number AS sales_rep
, (shiptoinfo.shipto_commission * 100.0) AS commission
, shipzone.shipzone_name AS zone
, taxzone.taxzone_code AS tax_zone
, shiptoinfo.shipto_shipvia AS ship_via
, shipform.shipform_name AS ship_form
, shipchrg.shipchrg_name AS shipping_charges
, CASE WHEN 
(shiptoinfo.shipto_ediprofile_id = 
     (-1)
) THEN 'No EDI'::text WHEN 
(shiptoinfo.shipto_ediprofile_id = 
     (-2)
) THEN 'Use Customer Master'::text ELSE getediprofilename
(shiptoinfo.shipto_ediprofile_id) END AS edi_profile
, shiptoinfo.shipto_comments AS general_notes
, shiptoinfo.shipto_shipcomments AS shipping_notes 
FROM custinfo
, (
     (
           (
                 (
                       (
                             (shiptoinfo 
                           LEFT JOIN shipchrg 
                                  ON (
                                         (shiptoinfo.shipto_shipchrg_id = shipchrg.shipchrg_id)
                                   )
                             )
                     LEFT JOIN cntct 
                            ON (
                                   (shiptoinfo.shipto_cntct_id = cntct.cntct_id)
                             )
                       )
               LEFT JOIN addr 
                      ON (
                             (shiptoinfo.shipto_addr_id = addr.addr_id)
                       )
                 )
         LEFT JOIN taxzone 
                ON (
                       (shiptoinfo.shipto_taxzone_id = taxzone.taxzone_id)
                 )
           )
   LEFT JOIN shipzone 
          ON (
                 (shiptoinfo.shipto_shipzone_id = shipzone.shipzone_id)
           )
     )
LEFT JOIN salesrep 
    ON (
           (shiptoinfo.shipto_salesrep_id = salesrep.salesrep_id)
     )
)
, shipform 
WHERE (
     (custinfo.cust_id = shiptoinfo.shipto_cust_id)
   AND (custinfo.cust_shipform_id = shipform.shipform_id)
);

Index - Schema api


View: api.custtax

Customer Tax Registration

api.custtax Structure
F-Key Name Type Description
customer_number character varying
tax_authority character varying
registration_number text
SELECT (custinfo.cust_number)::character varying AS customer_number
, (taxauth.taxauth_code)::character varying AS tax_authority
, taxreg.taxreg_number AS registration_number 
FROM custinfo
, taxauth
, taxreg 
WHERE (
     (
           (taxreg.taxreg_rel_type = 'C'::bpchar)
         AND (taxreg.taxreg_rel_id = custinfo.cust_id)
     )
   AND (taxreg.taxreg_taxauth_id = taxauth.taxauth_id)
);

Index - Schema api


View: api.employee

Employee

api.employee Structure
F-Key Name Type Description
code character varying
number character varying
active boolean
start_date date
contact_number text
honorific text
first text
middle text
last text
suffix text
job_title text
voice text
alternate text
fax text
email text
web text
contact_change text
address_number text
address1 text
address2 text
address3 text
city text
state text
postalcode text
country text
address_change text
site text
manager_code text
wage_type text
wage numeric
wage_currency character varying(3)
wage_period text
department text
shift text
is_user boolean
is_salesrep boolean
is_vendor boolean
notes text
image text
rate numeric
billing_currency character varying(3)
billing_period text
SELECT (e.emp_code)::character varying AS code
, (e.emp_number)::character varying AS number
, e.emp_active AS active
, e.emp_startdate AS start_date
, cntct.cntct_number AS contact_number
, cntct.cntct_honorific AS honorific
, cntct.cntct_first_name AS first
, cntct.cntct_middle AS middle
, cntct.cntct_last_name AS last
, cntct.cntct_suffix AS suffix
, cntct.cntct_title AS job_title
, cntct.cntct_phone AS voice
, cntct.cntct_phone2 AS alternate
, cntct.cntct_fax AS fax
, cntct.cntct_email AS email
, cntct.cntct_webaddr AS web
,''::text AS contact_change
, addr.addr_number AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postalcode
, addr.addr_country AS country
,''::text AS address_change
, whsinfo.warehous_code AS site
, m.emp_code AS manager_code
, CASE WHEN 
(e.emp_wage_type = 'H'::text) THEN 'Hourly'::text WHEN 
(e.emp_wage_type = 'S'::text) THEN 'Salaried'::text WHEN 
(e.emp_wage_type IS NULL) THEN NULL::text ELSE 'Error'::text END AS wage_type
, e.emp_wage AS wage
, curr_symbol.curr_abbr AS wage_currency
, CASE WHEN 
(e.emp_wage_period = 'H'::text) THEN 'Hour'::text WHEN 
(e.emp_wage_period = 'D'::text) THEN 'Day'::text WHEN 
(e.emp_wage_period = 'W'::text) THEN 'Week'::text WHEN 
(e.emp_wage_period = 'BW'::text) THEN 'Biweek'::text WHEN 
(e.emp_wage_period = 'M'::text) THEN 'Month'::text WHEN 
(e.emp_wage_period = 'Y'::text) THEN 'Year'::text WHEN 
(e.emp_wage_period IS NULL) THEN NULL::text ELSE 'Error'::text END AS wage_period
, dept.dept_number AS department
, shift.shift_number AS shift
, (crmacct.crmacct_usr_username IS NOT NULL) AS is_user
, (salesrep.salesrep_id IS NOT NULL) AS is_salesrep
, (vendinfo.vend_id IS NOT NULL) AS is_vendor
, e.emp_notes AS notes
, image.image_name AS image
, e.emp_extrate AS rate
, curr_symbol.curr_abbr AS billing_currency
, CASE WHEN 
(e.emp_extrate_period = 'H'::text) THEN 'Hour'::text WHEN 
(e.emp_extrate_period = 'D'::text) THEN 'Day'::text WHEN 
(e.emp_extrate_period = 'W'::text) THEN 'Week'::text WHEN 
(e.emp_extrate_period = 'BW'::text) THEN 'Biweek'::text WHEN 
(e.emp_extrate_period = 'M'::text) THEN 'Month'::text WHEN 
(e.emp_extrate_period = 'Y'::text) THEN 'Year'::text WHEN 
(e.emp_extrate_period IS NULL) THEN NULL::text ELSE 'Error'::text END AS billing_period 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (
                                                     (
                                                           (emp e 
                                                              JOIN crmacct 
                                                                ON (
                                                                       (e.emp_id = crmacct.crmacct_emp_id)
                                                                 )
                                                           )
                                                   LEFT JOIN cntct 
                                                          ON (
                                                                 (e.emp_cntct_id = cntct.cntct_id)
                                                           )
                                                     )
                                             LEFT JOIN addr 
                                                    ON (
                                                           (cntct.cntct_addr_id = addr.addr_id)
                                                     )
                                               )
                                       LEFT JOIN whsinfo 
                                              ON (
                                                     (e.emp_warehous_id = whsinfo.warehous_id)
                                               )
                                         )
                                 LEFT JOIN emp m 
                                        ON (
                                               (e.emp_mgr_emp_id = m.emp_id)
                                         )
                                   )
                           LEFT JOIN dept 
                                  ON (
                                         (e.emp_dept_id = dept.dept_id)
                                   )
                             )
                     LEFT JOIN shift 
                            ON (
                                   (e.emp_shift_id = shift.shift_id)
                             )
                       )
               LEFT JOIN salesrep 
                      ON (
                             (crmacct.crmacct_salesrep_id = salesrep.salesrep_id)
                       )
                 )
         LEFT JOIN vendinfo 
                ON (
                       (crmacct.crmacct_vend_id = vendinfo.vend_id)
                 )
           )
   LEFT JOIN image 
          ON (
                 (e.emp_image_id = image.image_id)
           )
     )
  JOIN curr_symbol 
    ON (
           (e.emp_wage_curr_id = curr_symbol.curr_id)
     )
);

Index - Schema api


View: api.employeechar

Employee Characteristics

api.employeechar Structure
F-Key Name Type Description
employee_code character varying
characteristic character varying
value text
SELECT (emp.emp_code)::character varying AS employee_code
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM emp
,"char"
, charass 
WHERE (
     (
           ('EMP'::text = charass.charass_target_type)
         AND (emp.emp_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.employeecomment

Employee Comment

api.employeecomment Structure
F-Key Name Type Description
code character varying
type character varying
date timestamp with time zone
username text
text text
SELECT (emp.emp_code)::character varying AS code
, (cmnttype.cmnttype_name)::character varying AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM emp
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'EMP'::text)
         AND (comment.comment_source_id = emp.emp_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.extshipmaint

External Shipping Maintenance

api.extshipmaint Structure
F-Key Name Type Description
so_number character varying
shipment_number character varying
shipper character varying
package_tracking_number character varying
void character(1)
billing_option text
weight numeric(16,4)
base_freight numeric(16,4)
base_freight_currency character varying(3)
total_freight numeric(16,4)
total_freight_currency character varying(3)
package_type text
tracking_number text
last_updated timestamp without time zone
SELECT (shipdata.shipdata_cohead_number)::character varying AS so_number
, (shipdata.shipdata_shiphead_number)::character varying AS shipment_number
, (shipdata.shipdata_shipper)::character varying AS shipper
, (shipdata.shipdata_cosmisc_packnum_tracknum)::character varying AS package_tracking_number
, shipdata.shipdata_void_ind AS void
, shipdata.shipdata_billing_option AS billing_option
, shipdata.shipdata_weight AS weight
, shipdata.shipdata_base_freight AS base_freight
, base.curr_abbr AS base_freight_currency
, shipdata.shipdata_total_freight AS total_freight
, total.curr_abbr AS total_freight_currency
, shipdata.shipdata_package_type AS package_type
, shipdata.shipdata_cosmisc_tracknum AS tracking_number
, shipdata.shipdata_lastupdated AS last_updated 
FROM shipdata
, curr_symbol base
, curr_symbol total 
WHERE (
     (shipdata.shipdata_base_freight_curr_id = base.curr_id)
   AND (shipdata.shipdata_total_freight_curr_id = total.curr_id)
)
ORDER BY shipdata.shipdata_cohead_number
, shipdata.shipdata_shiphead_number;

Index - Schema api


View: api.freightpricingscheduleitem

Freight Pricing Schedule Item

api.freightpricingscheduleitem Structure
F-Key Name Type Description
pricing_schedule character varying
qty_break numeric
qty_uom character varying
price numeric
price_type text
from_site text
to_shipzone text
ship_via text
freight_class text
SELECT (ipshead.ipshead_name)::character varying AS pricing_schedule
, ipsfreight.ipsfreight_qtybreak AS qty_break
, (qtyuom.uom_name)::character varying AS qty_uom
, ipsfreight.ipsfreight_price AS price
, CASE WHEN 
(ipsfreight.ipsfreight_type = 'F'::bpchar) THEN 'Flat Rate'::text ELSE 'Price Per UOM'::text END AS price_type
, COALESCE
(whsinfo.warehous_code
     ,'Any'::text
) AS from_site
, COALESCE
(shipzone.shipzone_name
     ,'Any'::text
) AS to_shipzone
, COALESCE
(ipsfreight.ipsfreight_shipvia
     ,'Any'::text
) AS ship_via
, COALESCE
(freightclass.freightclass_code
     ,'Any'::text
) AS freight_class 
FROM (
     (
           (
                 (
                       (ipsfreight 
                          JOIN ipshead 
                            ON (
                                   (ipsfreight.ipsfreight_ipshead_id = ipshead.ipshead_id)
                             )
                       )
               LEFT JOIN uom qtyuom 
                      ON (qtyuom.uom_item_weight)
                 )
         LEFT JOIN whsinfo 
                ON (
                       (whsinfo.warehous_id = ipsfreight.ipsfreight_warehous_id)
                 )
           )
   LEFT JOIN shipzone 
          ON (
                 (shipzone.shipzone_id = ipsfreight.ipsfreight_shipzone_id)
           )
     )
LEFT JOIN freightclass 
    ON (
           (freightclass.freightclass_id = ipsfreight.ipsfreight_freightclass_id)
     )
);

Index - Schema api


View: api.glaccount

GL Account

api.glaccount Structure
F-Key Name Type Description
company character varying
profit_center character varying
account_number character varying
sub_account character varying
description text
ext_reference text
type text
sub_type text
forward_update_trial_balances boolean
notes text
SELECT (accnt.accnt_company)::character varying AS company
, (accnt.accnt_profit)::character varying AS profit_center
, (accnt.accnt_number)::character varying AS account_number
, (accnt.accnt_sub)::character varying AS sub_account
, accnt.accnt_descrip AS description
, accnt.accnt_extref AS ext_reference
, CASE WHEN 
(accnt.accnt_type = 'A'::bpchar) THEN 'Asset'::text WHEN 
(accnt.accnt_type = 'L'::bpchar) THEN 'Liability'::text WHEN 
(accnt.accnt_type = 'E'::bpchar) THEN 'Expense'::text WHEN 
(accnt.accnt_type = 'R'::bpchar) THEN 'Revenue'::text WHEN 
(accnt.accnt_type = 'Q'::bpchar) THEN 'Equity'::text ELSE '?'::text END AS type
, accnt.accnt_subaccnttype_code AS sub_type
, accnt.accnt_forwardupdate AS forward_update_trial_balances
, accnt.accnt_comments AS notes 
FROM accnt 
ORDER BY accnt.accnt_company
, accnt.accnt_profit
, accnt.accnt_number
, accnt.accnt_sub;

Index - Schema api


View: api.incident

Incident

api.incident Structure
F-Key Name Type Description
incident_number integer
category text
description text
crm_account text
assigned_to text
status text
severity text
priority text
resolution text
contact_number text
honorific text
first text
middle text
last text
suffix text
job_title text
phone text
fax text
email text
contact_change text
notes text
item_number text
lot_serial_number text
ar_doc_type text
ar_doc_number text
SELECT incdt.incdt_number AS incident_number
, incdtcat.incdtcat_name AS category
, incdt.incdt_summary AS description
, crmacct.crmacct_number AS crm_account
, incdt.incdt_assigned_username AS assigned_to
, CASE WHEN 
(incdt.incdt_status = 'N'::bpchar) THEN 'New'::text WHEN 
(incdt.incdt_status = 'F'::bpchar) THEN 'Feedback'::text WHEN 
(incdt.incdt_status = 'C'::bpchar) THEN 'Confirmed'::text WHEN 
(incdt.incdt_status = 'A'::bpchar) THEN 'Assigned'::text WHEN 
(incdt.incdt_status = 'R'::bpchar) THEN 'Resolved'::text WHEN 
(incdt.incdt_status = 'L'::bpchar) THEN 'Closed'::text ELSE '?'::text END AS status
, incdtseverity.incdtseverity_name AS severity
, incdtpriority.incdtpriority_name AS priority
, incdtresolution.incdtresolution_name AS resolution
, cntct.cntct_number AS contact_number
, cntct.cntct_honorific AS honorific
, cntct.cntct_first_name AS first
, cntct.cntct_middle AS middle
, cntct.cntct_last_name AS last
, cntct.cntct_suffix AS suffix
, cntct.cntct_title AS job_title
, cntct.cntct_phone AS phone
, cntct.cntct_fax AS fax
, cntct.cntct_email AS email
,''::text AS contact_change
, incdt.incdt_descrip AS notes
, item.item_number
, incdt.incdt_lotserial AS lot_serial_number
, CASE WHEN 
(aropen.aropen_doctype = 'C'::bpchar) THEN 'C/M'::text WHEN 
(aropen.aropen_doctype = 'D'::bpchar) THEN 'D/M'::text WHEN 
(aropen.aropen_doctype = 'I'::bpchar) THEN 'Invoice'::text WHEN 
(aropen.aropen_doctype = 'R'::bpchar) THEN 'C/D'::text ELSE ''::text END AS ar_doc_type
, aropen.aropen_docnumber AS ar_doc_number 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (incdt 
                                       LEFT JOIN incdtcat 
                                              ON (
                                                     (incdtcat.incdtcat_id = incdt.incdt_incdtcat_id)
                                               )
                                         )
                                 LEFT JOIN crmacct 
                                        ON (
                                               (crmacct.crmacct_id = incdt.incdt_crmacct_id)
                                         )
                                   )
                           LEFT JOIN incdtseverity 
                                  ON (
                                         (incdtseverity.incdtseverity_id = incdt.incdt_incdtseverity_id)
                                   )
                             )
                     LEFT JOIN incdtpriority 
                            ON (
                                   (incdtpriority.incdtpriority_id = incdt.incdt_incdtpriority_id)
                             )
                       )
               LEFT JOIN incdtresolution 
                      ON (
                             (incdtresolution.incdtresolution_id = incdt.incdt_incdtresolution_id)
                       )
                 )
         LEFT JOIN cntct 
                ON (
                       (cntct.cntct_id = incdt.incdt_cntct_id)
                 )
           )
   LEFT JOIN item 
          ON (
                 (item.item_id = incdt.incdt_item_id)
           )
     )
LEFT JOIN aropen 
    ON (
           (aropen.aropen_id = incdt.incdt_aropen_id)
     )
);

Index - Schema api


View: api.incidentchar

Incident Characteristics

api.incidentchar Structure
F-Key Name Type Description
incident_number integer
characteristic character varying
value text
SELECT incdt.incdt_number AS incident_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value 
FROM incdt
,"char"
, charass 
WHERE (
     (
           ('INCDT'::text = charass.charass_target_type)
         AND (incdt.incdt_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.incidentcomment

Incident Comment

api.incidentcomment Structure
F-Key Name Type Description
incident_number integer
type text
date timestamp with time zone
username text
text text
public boolean
SELECT incdt.incdt_number AS incident_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text
, comment.comment_public AS public 
FROM incdt
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'INCDT'::text)
         AND (comment.comment_source_id = incdt.incdt_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.incidentfile

Incident File

api.incidentfile Structure
F-Key Name Type Description
incident_number integer
title text
url text
SELECT incdt.incdt_number AS incident_number
, url.url_title AS title
, url.url_url AS url 
FROM incdt
, url 
WHERE (
     (incdt.incdt_id = url.url_source_id)
   AND (url.url_source = 'INCDT'::text)
);

Index - Schema api


View: api.incidentimage

Incident Image

api.incidentimage Structure
F-Key Name Type Description
incident_number integer
image_name text
SELECT incdt.incdt_number AS incident_number
, image.image_name 
FROM incdt
, imageass
, image 
WHERE (
     (
           (incdt.incdt_id = imageass.imageass_source_id)
         AND (imageass.imageass_source = 'INCDT'::text)
     )
   AND (imageass.imageass_image_id = image.image_id)
);

Index - Schema api


View: api.invoice

This view can be used as an interface to import Invioce Header data directly into the system. Required fields will be checked and default values will be populated

api.invoice Structure
F-Key Name Type Description
invoice_number text
order_number text
invoice_date date
ship_date date
order_date date
sale_type text
sales_rep text
commission numeric(20,10)
tax_zone text
terms text
customer_number text
billto_name text
billto_address1 text
billto_address2 text
billto_address3 text
billto_city text
billto_state text
billto_postal_code text
billto_country text
billto_phone text
shipto_number text
shipto_name text
shipto_address1 text
shipto_address2 text
shipto_address3 text
shipto_city text
shipto_state text
shipto_postal_code text
shipto_country text
shipto_shipzone text
shipto_phone text
po_number text
ship_via text
project_number text
fob text
misc_charge_description text
misc_charge numeric(16,2)
misc_charge_account_number text
freight numeric(16,2)
currency character varying(3)
payment numeric(16,2)
notes text
SELECT invchead.invchead_invcnumber AS invoice_number
, invchead.invchead_ordernumber AS order_number
, invchead.invchead_invcdate AS invoice_date
, invchead.invchead_shipdate AS ship_date
, invchead.invchead_orderdate AS order_date
, saletype.saletype_code AS sale_type
, salesrep.salesrep_number AS sales_rep
, invchead.invchead_commission AS commission
, COALESCE
(taxzone.taxzone_code
     ,'None'::text
) AS tax_zone
, terms.terms_code AS terms
, custinfo.cust_number AS customer_number
, invchead.invchead_billto_name AS billto_name
, invchead.invchead_billto_address1 AS billto_address1
, invchead.invchead_billto_address2 AS billto_address2
, invchead.invchead_billto_address3 AS billto_address3
, invchead.invchead_billto_city AS billto_city
, invchead.invchead_billto_state AS billto_state
, invchead.invchead_billto_zipcode AS billto_postal_code
, invchead.invchead_billto_country AS billto_country
, invchead.invchead_billto_phone AS billto_phone
, shiptoinfo.shipto_num AS shipto_number
, invchead.invchead_shipto_name AS shipto_name
, invchead.invchead_shipto_address1 AS shipto_address1
, invchead.invchead_shipto_address2 AS shipto_address2
, invchead.invchead_shipto_address3 AS shipto_address3
, invchead.invchead_shipto_city AS shipto_city
, invchead.invchead_shipto_state AS shipto_state
, invchead.invchead_shipto_zipcode AS shipto_postal_code
, invchead.invchead_shipto_country AS shipto_country
, shipzone.shipzone_name AS shipto_shipzone
, invchead.invchead_shipto_phone AS shipto_phone
, invchead.invchead_ponumber AS po_number
, invchead.invchead_shipvia AS ship_via
, prj.prj_number AS project_number
, invchead.invchead_fob AS fob
, invchead.invchead_misc_descrip AS misc_charge_description
, invchead.invchead_misc_amount AS misc_charge
, CASE WHEN 
(invchead.invchead_misc_accnt_id = 
     (-1)
) THEN NULL::text ELSE formatglaccount
(invchead.invchead_misc_accnt_id) END AS misc_charge_account_number
, invchead.invchead_freight AS freight
, curr.curr_abbr AS currency
, invchead.invchead_payment AS payment
, invchead.invchead_notes AS notes 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (invchead 
                                             LEFT JOIN custinfo 
                                                    ON (
                                                           (custinfo.cust_id = invchead.invchead_cust_id)
                                                     )
                                               )
                                       LEFT JOIN shiptoinfo 
                                              ON (
                                                     (shiptoinfo.shipto_id = invchead.invchead_shipto_id)
                                               )
                                         )
                                 LEFT JOIN prj 
                                        ON (
                                               (prj.prj_id = invchead.invchead_prj_id)
                                         )
                                   )
                           LEFT JOIN curr_symbol curr 
                                  ON (
                                         (curr.curr_id = invchead.invchead_curr_id)
                                   )
                             )
                     LEFT JOIN salesrep 
                            ON (
                                   (salesrep.salesrep_id = invchead.invchead_salesrep_id)
                             )
                       )
               LEFT JOIN terms 
                      ON (
                             (terms.terms_id = invchead.invchead_terms_id)
                       )
                 )
         LEFT JOIN taxzone 
                ON (
                       (taxzone.taxzone_id = invchead.invchead_taxzone_id)
                 )
           )
   LEFT JOIN saletype 
          ON (
                 (invchead.invchead_saletype_id = saletype.saletype_id)
           )
     )
LEFT JOIN shipzone 
    ON (
           (invchead.invchead_shipzone_id = shipzone.shipzone_id)
     )
);

Index - Schema api


View: api.invoiceline

This view can be used as an interface to import Invoice Line Items data directly into the system. Required fields will be checked and default values will be populated

api.invoiceline Structure
F-Key Name Type Description
invoice_number text
line_number integer
item_number text
misc_item_number text
site text
misc_item_description text
sales_category text
customer_part_number text
qty_ordered numeric(20,6)
qty_billed numeric(20,6)
update_inventory boolean
net_unit_price numeric(20,4)
tax_type text
qty_uom text
price_uom text
notes text
alternate_rev_account text
SELECT invchead.invchead_invcnumber AS invoice_number
, invcitem.invcitem_linenumber AS line_number
, item.item_number
, invcitem.invcitem_number AS misc_item_number
, whsinfo.warehous_code AS site
, invcitem.invcitem_descrip AS misc_item_description
, salescat.salescat_name AS sales_category
, invcitem.invcitem_custpn AS customer_part_number
, invcitem.invcitem_ordered AS qty_ordered
, invcitem.invcitem_billed AS qty_billed
, invcitem.invcitem_updateinv AS update_inventory
, invcitem.invcitem_price AS net_unit_price
, COALESCE
(taxtype.taxtype_name
     ,'None'::text
) AS tax_type
, COALESCE
(qty_uom.uom_name
     ,'None'::text
) AS qty_uom
, COALESCE
(price_uom.uom_name
     ,'None'::text
) AS price_uom
, invcitem.invcitem_notes AS notes
, CASE WHEN 
(invcitem.invcitem_rev_accnt_id IS NOT NULL) THEN formatglaccount
(invcitem.invcitem_rev_accnt_id) ELSE NULL::text END AS alternate_rev_account 
FROM (
     (
           (
                 (
                       (
                             (
                                   (invcitem 
                                 LEFT JOIN invchead 
                                        ON (
                                               (invcitem.invcitem_invchead_id = invchead.invchead_id)
                                         )
                                   )
                           LEFT JOIN item 
                                  ON (
                                         (item.item_id = invcitem.invcitem_item_id)
                                   )
                             )
                     LEFT JOIN whsinfo 
                            ON (
                                   (invcitem.invcitem_warehous_id = whsinfo.warehous_id)
                             )
                       )
               LEFT JOIN salescat 
                      ON (
                             (salescat.salescat_id = invcitem.invcitem_salescat_id)
                       )
                 )
         LEFT JOIN taxtype 
                ON (
                       (taxtype.taxtype_id = invcitem.invcitem_taxtype_id)
                 )
           )
   LEFT JOIN uom qty_uom 
          ON (
                 (qty_uom.uom_id = invcitem.invcitem_qty_uom_id)
           )
     )
LEFT JOIN uom price_uom 
    ON (
           (price_uom.uom_id = invcitem.invcitem_price_uom_id)
     )
);

Index - Schema api


View: api.item

Item

api.item Structure
F-Key Name Type Description
item_number character varying
active boolean
description1 text
description2 text
item_type text
maximum_desired_cost numeric(16,6)
class_code text
inventory_uom text
pick_list_item boolean
fractional boolean
configured boolean
item_is_sold boolean
product_category text
exclusive boolean
list_price numeric(16,4)
list_price_uom text
upc_code text
product_weight numeric(16,2)
packaging_weight numeric(16,2)
notes text
ext_description text
SELECT (item.item_number)::character varying AS item_number
, item.item_active AS active
, item.item_descrip1 AS description1
, item.item_descrip2 AS description2
, CASE WHEN 
(item.item_type = 'P'::bpchar) THEN 'Purchased'::text WHEN 
(item.item_type = 'M'::bpchar) THEN 'Manufactured'::text WHEN 
(item.item_type = 'J'::bpchar) THEN 'Job'::text WHEN 
(item.item_type = 'K'::bpchar) THEN 'Kit'::text WHEN 
(item.item_type = 'F'::bpchar) THEN 'Phantom'::text WHEN 
(item.item_type = 'R'::bpchar) THEN 'Reference'::text WHEN 
(item.item_type = 'S'::bpchar) THEN 'Costing'::text WHEN 
(item.item_type = 'T'::bpchar) THEN 'Tooling'::text WHEN 
(item.item_type = 'O'::bpchar) THEN 'Outside Process'::text WHEN 
(item.item_type = 'L'::bpchar) THEN 'Planning'::text WHEN 
(item.item_type = 'B'::bpchar) THEN 'Breeder'::text WHEN 
(item.item_type = 'C'::bpchar) THEN 'Co-Product'::text WHEN 
(item.item_type = 'Y'::bpchar) THEN 'By-Product'::text ELSE NULL::text END AS item_type
, item.item_maxcost AS maximum_desired_cost
, classcode.classcode_code AS class_code
, i.uom_name AS inventory_uom
, item.item_picklist AS pick_list_item
, item.item_fractional AS fractional
, item.item_config AS configured
, item.item_sold AS item_is_sold
, prodcat.prodcat_code AS product_category
, item.item_exclusive AS exclusive
, item.item_listprice AS list_price
, p.uom_name AS list_price_uom
, item.item_upccode AS upc_code
, item.item_prodweight AS product_weight
, item.item_packweight AS packaging_weight
, item.item_comments AS notes
, item.item_extdescrip AS ext_description 
FROM (item 
LEFT JOIN prodcat 
    ON (
           (item.item_prodcat_id = prodcat.prodcat_id)
     )
)
, classcode
, uom i
, uom p 
WHERE (
     (
           (item.item_classcode_id = classcode.classcode_id)
         AND (item.item_inv_uom_id = i.uom_id)
     )
   AND (item.item_price_uom_id = p.uom_id)
)
ORDER BY (item.item_number)::character varying;

Index - Schema api


View: api.itemalias

Item Alias

api.itemalias Structure
F-Key Name Type Description
item_number character varying
alias_number text
use_description boolean
description1 text
description2 text
comments text
SELECT (item.item_number)::character varying AS item_number
, itemalias.itemalias_number AS alias_number
, itemalias.itemalias_usedescrip AS use_description
, itemalias.itemalias_descrip1 AS description1
, itemalias.itemalias_descrip2 AS description2
, itemalias.itemalias_comments AS comments 
FROM item
, itemalias 
WHERE (item.item_id = itemalias.itemalias_item_id);

Index - Schema api


View: api.itemchar

Item Characteristic

api.itemchar Structure
F-Key Name Type Description
item_number character varying
characteristic character varying
value text
is_default boolean
SELECT (item.item_number)::character varying AS item_number
, ("char".char_name)::character varying AS characteristic
, charass.charass_value AS value
, charass.charass_default AS is_default 
FROM item
,"char"
, charass 
WHERE (
     (
           ('I'::text = charass.charass_target_type)
         AND (item.item_id = charass.charass_target_id)
     )
   AND (charass.charass_char_id = "char".char_id)
);

Index - Schema api


View: api.itemcomment

Item Comments

api.itemcomment Structure
F-Key Name Type Description
item_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (item.item_number)::character varying AS item_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM item
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'I'::text)
         AND (comment.comment_source_id = item.item_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.itemcost

Item Cost

api.itemcost Structure
F-Key Name Type Description
item_number character varying(100)
costing_element character varying(100)
actual_cost numeric(16,6)
currency character varying(3)
post_to_standard boolean
SELECT (item.item_number)::character varying
(100) AS item_number
, (costelem.costelem_type)::character varying
(100) AS costing_element
, itemcost.itemcost_actcost AS actual_cost
, curr_symbol.curr_abbr AS currency
, false AS post_to_standard 
FROM (
     (
           (itemcost 
         LEFT JOIN item 
                ON (
                       (itemcost.itemcost_item_id = item.item_id)
                 )
           )
   LEFT JOIN costelem 
          ON (
                 (itemcost.itemcost_costelem_id = costelem.costelem_id)
           )
     )
LEFT JOIN curr_symbol 
    ON (
           (itemcost.itemcost_curr_id = curr_symbol.curr_id)
     )
)
ORDER BY (item.item_number)::character varying
(100)
, (costelem.costelem_type)::character varying
(100);

Index - Schema api


View: api.itemfile

Item File

api.itemfile Structure
F-Key Name Type Description
item_number character varying
title text
url text
SELECT (item.item_number)::character varying AS item_number
, url.url_title AS title
, url.url_url AS url 
FROM item
, url 
WHERE (
     (item.item_id = url.url_source_id)
   AND (url.url_source = 'I'::text)
);

Index - Schema api


View: api.itemimage

Item Image

api.itemimage Structure
F-Key Name Type Description
item_number character varying
purpose text
image_name text
SELECT (item.item_number)::character varying AS item_number
, CASE WHEN 
(imageass.imageass_purpose = 'P'::bpchar) THEN 'Product Description'::text WHEN 
(imageass.imageass_purpose = 'I'::bpchar) THEN 'Inventory Description'::text WHEN 
(imageass.imageass_purpose = 'E'::bpchar) THEN 'Engineering Reference'::text WHEN 
(imageass.imageass_purpose = 'M'::bpchar) THEN 'Miscellaneous'::text ELSE 'Other'::text END AS purpose
, image.image_name 
FROM item
, imageass
, image 
WHERE (
     (
           (item.item_id = imageass.imageass_source_id)
         AND (imageass.imageass_source = 'I'::text)
     )
   AND (imageass.imageass_image_id = image.image_id)
);

Index - Schema api


View: api.itemsite

Item Site

api.itemsite Structure
F-Key Name Type Description
item_number character varying
site character varying
active boolean
wo_supplied_at_site boolean
create_wos boolean
po_supplied_at_site boolean
create_prs boolean
create_soprs boolean
create_sopos boolean
dropship boolean
sold_from_site boolean
ranking integer
cost_method text
control_method text
planner_code text
cost_category text
stocked boolean
abc_class character(1)
allow_automatic_updates boolean
cycl_cnt_freq integer
event_fence integer
multiple_location_control boolean
location text
user_defined_location text
location_comment text
disallow_blank_wip_locations boolean
enforce_order_parameters boolean
reorder_level numeric(18,6)
order_up_to numeric(18,6)
minimum_order numeric(18,6)
maximum_order numeric(18,6)
order_multiple numeric(18,6)
enforce_on_manual_orders boolean
planning_system text
group_mps_mrp_orders integer
first_group boolean
mps_time_fence integer
lead_time integer
safety_stock numeric(18,6)
supplied_from_site text
notes text
perishable boolean
require_warranty boolean
auto_register boolean
SELECT (item.item_number)::character varying AS item_number
, (whsinfo.warehous_code)::character varying AS site
, itemsite.itemsite_active AS active
, itemsite.itemsite_wosupply AS wo_supplied_at_site
, itemsite.itemsite_createwo AS create_wos
, itemsite.itemsite_posupply AS po_supplied_at_site
, itemsite.itemsite_createpr AS create_prs
, itemsite.itemsite_createsopr AS create_soprs
, itemsite.itemsite_createsopo AS create_sopos
, itemsite.itemsite_dropship AS dropship
, itemsite.itemsite_sold AS sold_from_site
, itemsite.itemsite_soldranking AS ranking
, CASE WHEN 
(itemsite.itemsite_costmethod = 'N'::bpchar) THEN 'None'::text WHEN 
(itemsite.itemsite_costmethod = 'A'::bpchar) THEN 'Average'::text WHEN 
(itemsite.itemsite_costmethod = 'S'::bpchar) THEN 'Standard'::text WHEN 
(itemsite.itemsite_costmethod = 'J'::bpchar) THEN 'Job'::text ELSE NULL::text END AS cost_method
, CASE WHEN 
(itemsite.itemsite_controlmethod = 'N'::bpchar) THEN 'None'::text WHEN 
(itemsite.itemsite_controlmethod = 'R'::bpchar) THEN 'Regular'::text WHEN 
(itemsite.itemsite_controlmethod = 'S'::bpchar) THEN 'Serial #'::text WHEN 
(itemsite.itemsite_controlmethod = 'L'::bpchar) THEN 'Lot #'::text ELSE NULL::text END AS control_method
, plancode.plancode_code AS planner_code
, costcat.costcat_code AS cost_category
, itemsite.itemsite_stocked AS stocked
, itemsite.itemsite_abcclass AS abc_class
, itemsite.itemsite_autoabcclass AS allow_automatic_updates
, itemsite.itemsite_cyclecountfreq AS cycl_cnt_freq
, itemsite.itemsite_eventfence AS event_fence
, itemsite.itemsite_loccntrl AS multiple_location_control
, formatlocationname
(itemsite.itemsite_location_id) AS location
, itemsite.itemsite_location AS user_defined_location
, itemsite.itemsite_location_comments AS location_comment
, itemsite.itemsite_disallowblankwip AS disallow_blank_wip_locations
, itemsite.itemsite_useparams AS enforce_order_parameters
, itemsite.itemsite_reorderlevel AS reorder_level
, itemsite.itemsite_ordertoqty AS order_up_to
, itemsite.itemsite_minordqty AS minimum_order
, itemsite.itemsite_maxordqty AS maximum_order
, itemsite.itemsite_multordqty AS order_multiple
, itemsite.itemsite_useparamsmanual AS enforce_on_manual_orders
, CASE WHEN 
(itemsite.itemsite_planning_type = 'N'::bpchar) THEN 'None'::text WHEN 
(itemsite.itemsite_planning_type = 'M'::bpchar) THEN 'MRP'::text WHEN 
(itemsite.itemsite_planning_type = 'S'::bpchar) THEN 'MPS'::text ELSE NULL::text END AS planning_system
, itemsite.itemsite_ordergroup AS group_mps_mrp_orders
, itemsite.itemsite_ordergroup_first AS first_group
, itemsite.itemsite_mps_timefence AS mps_time_fence
, itemsite.itemsite_leadtime AS lead_time
, itemsite.itemsite_safetystock AS safety_stock
, COALESCE
(
     (
      SELECT whsinfo.warehous_code 
        FROM (itemsite supplysite 
              JOIN whsinfo 
                ON (
                       (whsinfo.warehous_id = supplysite.itemsite_warehous_id)
                 )
           )
       WHERE (supplysite.itemsite_id = itemsite.itemsite_supply_itemsite_id)
     )
     ,'None'::text
) AS supplied_from_site
, itemsite.itemsite_notes AS notes
, itemsite.itemsite_perishable AS perishable
, itemsite.itemsite_warrpurc AS require_warranty
, itemsite.itemsite_autoreg AS auto_register 
FROM item
, (itemsite 
LEFT JOIN location 
    ON (
           (itemsite.itemsite_location_id = location.location_id)
     )
)
, plancode
, costcat
, whsinfo 
WHERE (
     (
           (
                 (item.item_id = itemsite.itemsite_item_id)
               AND (itemsite.itemsite_plancode_id = plancode.plancode_id)
           )
         AND (itemsite.itemsite_costcat_id = costcat.costcat_id)
     )
   AND (itemsite.itemsite_warehous_id = whsinfo.warehous_id)
);

Index - Schema api


View: api.itemsitecomment

Item Site Comments

api.itemsitecomment Structure
F-Key Name Type Description
item_number character varying
site character varying
type text
date timestamp with time zone
username text
text text
SELECT (item.item_number)::character varying AS item_number
, (whsinfo.warehous_code)::character varying AS site
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM itemsite
, item
, whsinfo
, cmnttype
, comment 
WHERE (
     (itemsite.itemsite_item_id = item.item_id)
   AND (
           (
                 (
                       (itemsite.itemsite_warehous_id = whsinfo.warehous_id)
                     AND (comment.comment_source = 'IS'::text)
                 )
               AND (comment.comment_source_id = itemsite.itemsite_id)
           )
         AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
     )
);

Index - Schema api


View: api.itemsource

Item Source

api.itemsource Structure
F-Key Name Type Description
item_number character varying
vendor character varying
vendor_item_number text
active boolean
itemsrc_default boolean
vendor_uom text
inventory_vendor_uom_ratio numeric(20,10)
minimum_order numeric(18,6)
order_multiple numeric(18,6)
vendor_ranking integer
lead_time integer
notes text
vendor_description text
manufacturer_name text
manufacturer_item_number text
manufacturer_description text
SELECT (item.item_number)::character varying AS item_number
, (vendinfo.vend_number)::character varying AS vendor
, itemsrc.itemsrc_vend_item_number AS vendor_item_number
, itemsrc.itemsrc_active AS active
, itemsrc.itemsrc_default
, itemsrc.itemsrc_vend_uom AS vendor_uom
, itemsrc.itemsrc_invvendoruomratio AS inventory_vendor_uom_ratio
, itemsrc.itemsrc_minordqty AS minimum_order
, itemsrc.itemsrc_multordqty AS order_multiple
, itemsrc.itemsrc_ranking AS vendor_ranking
, itemsrc.itemsrc_leadtime AS lead_time
, itemsrc.itemsrc_comments AS notes
, itemsrc.itemsrc_vend_item_descrip AS vendor_description
, itemsrc.itemsrc_manuf_name AS manufacturer_name
, itemsrc.itemsrc_manuf_item_number AS manufacturer_item_number
, itemsrc.itemsrc_manuf_item_descrip AS manufacturer_description 
FROM (
     (itemsrc 
   LEFT JOIN item 
          ON (
                 (itemsrc.itemsrc_item_id = item.item_id)
           )
     )
LEFT JOIN vendinfo 
    ON (
           (itemsrc.itemsrc_vend_id = vendinfo.vend_id)
     )
)
ORDER BY (item.item_number)::character varying
(100)
, (vendinfo.vend_number)::character varying
(100);

Index - Schema api


View: api.itemsourceprice

Item Source Price

api.itemsourceprice Structure
F-Key Name Type Description
item_number character varying
vendor character varying
qty_break numeric(18,6)
price_per_unit numeric(16,6)
currency character varying(3)
SELECT (item.item_number)::character varying AS item_number
, (vendinfo.vend_number)::character varying AS vendor
, itemsrcp.itemsrcp_qtybreak AS qty_break
, itemsrcp.itemsrcp_price AS price_per_unit
, curr_symbol.curr_abbr AS currency 
FROM (
     (
           (
                 (itemsrcp 
               LEFT JOIN itemsrc 
                      ON (
                             (itemsrc.itemsrc_id = itemsrcp.itemsrcp_itemsrc_id)
                       )
                 )
         LEFT JOIN item 
                ON (
                       (itemsrc.itemsrc_item_id = item.item_id)
                 )
           )
   LEFT JOIN vendinfo 
          ON (
                 (itemsrc.itemsrc_vend_id = vendinfo.vend_id)
           )
     )
LEFT JOIN curr_symbol 
    ON (
           (itemsrcp.itemsrcp_curr_id = curr_symbol.curr_id)
     )
)
ORDER BY (item.item_number)::character varying
(100)
, (vendinfo.vend_number)::character varying
(100);

Index - Schema api


View: api.itemsubstitute

Item Substitute

api.itemsubstitute Structure
F-Key Name Type Description
root_item_number character varying
substitute_item_number character varying
sub_parent_uom_ratio numeric(20,10)
ranking integer
SELECT (p.item_number)::character varying AS root_item_number
, (s.item_number)::character varying AS substitute_item_number
, itemsub.itemsub_uomratio AS sub_parent_uom_ratio
, itemsub.itemsub_rank AS ranking 
FROM item p
, item s
, itemsub 
WHERE (
     (p.item_id = itemsub.itemsub_parent_item_id)
   AND (s.item_id = itemsub.itemsub_sub_item_id)
);

Index - Schema api


View: api.itemtaxtype

Item Tax Type

api.itemtaxtype Structure
F-Key Name Type Description
item_number character varying
tax_zone character varying
tax_type text
SELECT (item.item_number)::character varying AS item_number
, CASE WHEN 
(taxzone.taxzone_id IS NULL) THEN 'Any'::character varying ELSE 
(taxzone.taxzone_code)::character varying END AS tax_zone
, taxtype.taxtype_name AS tax_type 
FROM item
, (itemtax 
LEFT JOIN taxzone 
    ON (
           (itemtax.itemtax_taxzone_id = taxzone.taxzone_id)
     )
)
, taxtype 
WHERE (
     (item.item_id = itemtax.itemtax_item_id)
   AND (itemtax.itemtax_taxtype_id = taxtype.taxtype_id)
);

Index - Schema api


View: api.itemuomconversion

Item Unit of Measure Conversion

api.itemuomconversion Structure
F-Key Name Type Description
item_number character varying
uom character varying
uom_value numeric(20,10)
per_uom text
per_uom_value numeric(20,10)
fractional boolean
selected_types text[]
SELECT (item.item_number)::character varying AS item_number
, (f.uom_name)::character varying AS uom
, itemuomconv.itemuomconv_from_value AS uom_value
, p.uom_name AS per_uom
, itemuomconv.itemuomconv_to_value AS per_uom_value
, itemuomconv.itemuomconv_fractional AS fractional
, fetchitemuomconvtypes
(itemuomconv.itemuomconv_id) AS selected_types 
FROM item
, itemuomconv
, uom f
, uom p 
WHERE (
     (
           (item.item_id = itemuomconv.itemuomconv_item_id)
         AND (itemuomconv.itemuomconv_from_uom_id = f.uom_id)
     )
   AND (itemuomconv.itemuomconv_to_uom_id = p.uom_id)
);

Index - Schema api


View: api.journalentry

Journal Entry

api.journalentry Structure
F-Key Name Type Description
currency character varying(3)
amount numeric(20,2)
dist_date date
doc_number text
debit text
credit text
notes text
SELECT curr_symbol.curr_abbr AS currency
, c.gltrans_amount AS amount
, c.gltrans_date AS dist_date
, c.gltrans_docnumber AS doc_number
, formatglaccount
(da.accnt_id) AS debit
, formatglaccount
(ca.accnt_id) AS credit
, c.gltrans_notes AS notes 
FROM gltrans d
, gltrans c
, accnt da
, accnt ca
, curr_symbol 
WHERE (
     (
           (
                 (
                       (
                             (
                                   (
                                         (d.gltrans_sequence = c.gltrans_sequence)
                                       AND (d.gltrans_accnt_id = da.accnt_id)
                                   )
                                 AND (c.gltrans_accnt_id = ca.accnt_id)
                             )
                           AND (d.gltrans_amount < 
                                   (0)::numeric
                             )
                       )
                     AND (c.gltrans_amount > 
                             (0)::numeric
                       )
                 )
               AND (d.gltrans_doctype = 'JE'::text)
           )
         AND (c.gltrans_doctype = 'JE'::text)
     )
   AND (curr_symbol.curr_id = basecurrid
           ()
     )
)
ORDER BY d.gltrans_date DESC;

Index - Schema api


View: api.location

Location

api.location Structure
F-Key Name Type Description
site character varying
aisle character varying
rack character varying
bin character varying
location character varying
zone text
netable boolean
restricted boolean
description text
SELECT (whsinfo.warehous_code)::character varying AS site
, (location.location_aisle)::character varying AS aisle
, (location.location_rack)::character varying AS rack
, (location.location_bin)::character varying AS bin
, (location.location_name)::character varying AS location
, whsezone.whsezone_name AS zone
, location.location_netable AS netable
, location.location_restrict AS restricted
, location.location_descrip AS description 
FROM (
     (location 
   LEFT JOIN whsinfo 
          ON (
                 (whsinfo.warehous_id = location.location_warehous_id)
           )
     )
LEFT JOIN whsezone 
    ON (
           (whsezone.whsezone_id = location.location_whsezone_id)
     )
);

Index - Schema api


View: api.misccounttag

Miscellaneous Count Tag

api.misccounttag Structure
F-Key Name Type Description
site text
item_number text
quantity numeric
comment text
SELECT'This view is for inserts only'::text AS site
,'This view is for inserts only'::text AS item_number
, (0)::numeric AS quantity
,'This view is for inserts only'::text AS comment;

Index - Schema api


View: api.pricingschedule

Pricing Schedule

api.pricingschedule Structure
F-Key Name Type Description
name character varying
description text
effective text
expires text
currency character varying(3)
SELECT (ipshead.ipshead_name)::character varying AS name
, ipshead.ipshead_descrip AS description
, formatdate
(ipshead.ipshead_effective
     ,'Always'::text
) AS effective
, formatdate
(ipshead.ipshead_expires
     ,'Never'::text
) AS expires
, curr_symbol.curr_abbr AS currency 
FROM ipshead
, curr_symbol 
WHERE (curr_symbol.curr_id = ipshead.ipshead_curr_id);

Index - Schema api


View: api.pricingscheduleassign

Pricing Schedule Assignments

api.pricingscheduleassign Structure
F-Key Name Type Description
customer_number character varying
customer_shipto character varying
customer_shipto_pattern character varying
customer_type character varying
customer_type_pattern character varying
pricing_schedule character varying
SELECT (COALESCE
     (custinfo.cust_number
           ,'Any'::text
     )
)::character varying AS customer_number
, (COALESCE
     (shiptoinfo.shipto_num
           ,'Any'::text
     )
)::character varying AS customer_shipto
, (COALESCE
     (ipsass.ipsass_shipto_pattern
           ,'N/A'::text
     )
)::character varying AS customer_shipto_pattern
, (COALESCE
     (custtype.custtype_code
           ,'N/A'::text
     )
)::character varying AS customer_type
, (COALESCE
     (ipsass.ipsass_custtype_pattern
           ,'N/A'::text
     )
)::character varying AS customer_type_pattern
, (ipshead.ipshead_name)::character varying AS pricing_schedule 
FROM (
     (
           (
                 (ipshead 
                    JOIN ipsass 
                      ON (
                             (ipshead.ipshead_id = ipsass.ipsass_ipshead_id)
                       )
                 )
         LEFT JOIN custinfo 
                ON (
                       (ipsass.ipsass_cust_id = custinfo.cust_id)
                 )
           )
   LEFT JOIN custtype 
          ON (
                 (ipsass.ipsass_custtype_id = custtype.custtype_id)
           )
     )
LEFT JOIN shiptoinfo 
    ON (
           (ipsass.ipsass_shipto_id = shiptoinfo.shipto_id)
     )
)
ORDER BY (COALESCE
     (custinfo.cust_number
           ,'Any'::text
     )
)::character varying
, (COALESCE
     (shiptoinfo.shipto_num
           ,'Any'::text
     )
)::character varying
, (COALESCE
     (custtype.custtype_code
           ,'N/A'::text
     )
)::character varying
, (COALESCE
     (ipsass.ipsass_custtype_pattern
           ,'N/A'::text
     )
)::character varying
, (ipshead.ipshead_name)::character varying;

Index - Schema api


View: api.pricingscheduleitem

Pricing Schedule Item

api.pricingscheduleitem Structure
F-Key Name Type Description
pricing_schedule character varying
type character varying
item_number character varying
product_category character varying
qty_break numeric(18,6)
qty_uom character varying
price_uom character varying
price numeric(16,4)
percent numeric(10,6)
fixedamt numeric(16,4)
pricing_type character varying
SELECT (ipshead.ipshead_name)::character varying AS pricing_schedule
, CASE WHEN 
(COALESCE
     (ipsiteminfo.ipsitem_item_id
           , (-1)
     ) > 0
) THEN 'Item'::character varying ELSE 'Product Category'::character varying END AS type
, (COALESCE
     (item.item_number
           ,''::text
     )
)::character varying AS item_number
, (COALESCE
     (prodcat.prodcat_code
           ,''::text
     )
)::character varying AS product_category
, ipsiteminfo.ipsitem_qtybreak AS qty_break
, (qtyuom.uom_name)::character varying AS qty_uom
, (priceuom.uom_name)::character varying AS price_uom
, ipsiteminfo.ipsitem_price AS price
, ipsiteminfo.ipsitem_discntprcnt AS percent
, ipsiteminfo.ipsitem_fixedamtdiscount AS fixedamt
, CASE WHEN 
(ipsiteminfo.ipsitem_type = 'N'::bpchar) THEN 'Nominal'::character varying WHEN 
(ipsiteminfo.ipsitem_type = 'D'::bpchar) THEN 'Discount'::character varying WHEN 
(ipsiteminfo.ipsitem_type = 'M'::bpchar) THEN 'Markup'::character varying ELSE NULL::character varying END AS pricing_type 
FROM (
     (
           (
                 (
                       (ipsiteminfo 
                          JOIN ipshead 
                            ON (
                                   (ipsiteminfo.ipsitem_ipshead_id = ipshead.ipshead_id)
                             )
                       )
               LEFT JOIN item 
                      ON (
                             (ipsiteminfo.ipsitem_item_id = item.item_id)
                       )
                 )
         LEFT JOIN prodcat 
                ON (
                       (ipsiteminfo.ipsitem_prodcat_id = prodcat.prodcat_id)
                 )
           )
   LEFT JOIN uom qtyuom 
          ON (
                 (ipsiteminfo.ipsitem_qty_uom_id = qtyuom.uom_id)
           )
     )
LEFT JOIN uom priceuom 
    ON (
           (ipsiteminfo.ipsitem_price_uom_id = priceuom.uom_id)
     )
);

Index - Schema api


View: api.pricingscheduleitemchar

Pricing Schedule Item Characteristics

api.pricingscheduleitemchar Structure
F-Key Name Type Description
pricing_schedule character varying
item_number character varying
qty_break numeric(18,6)
qty_uom character varying
price_uom character varying
characteristic character varying
value character varying
price numeric(16,4)
SELECT (ipshead.ipshead_name)::character varying AS pricing_schedule
, (item.item_number)::character varying AS item_number
, ipsiteminfo.ipsitem_qtybreak AS qty_break
, (qtyuom.uom_name)::character varying AS qty_uom
, (priceuom.uom_name)::character varying AS price_uom
, ("char".char_name)::character varying AS characteristic
, (ipsitemchar.ipsitemchar_value)::character varying AS value
, ipsitemchar.ipsitemchar_price AS price 
FROM ipshead
, ipsiteminfo
, ipsitemchar
, item
,"char"
, uom qtyuom
, uom priceuom 
WHERE (
     (
           (
                 (
                       (
                             (ipshead.ipshead_id = ipsiteminfo.ipsitem_ipshead_id)
                           AND (ipsiteminfo.ipsitem_id = ipsitemchar.ipsitemchar_ipsitem_id)
                       )
                     AND (ipsiteminfo.ipsitem_item_id = item.item_id)
                 )
               AND (ipsiteminfo.ipsitem_qty_uom_id = qtyuom.uom_id)
           )
         AND (ipsiteminfo.ipsitem_price_uom_id = priceuom.uom_id)
     )
   AND (ipsitemchar.ipsitemchar_char_id = "char".char_id)
);

Index - Schema api


View: api.project

Project

api.project Structure
F-Key Name Type Description
number text
name text
description text
owner text
assigned_to text
sales_orders boolean
work_orders boolean
purchase_orders boolean
status text
due date
assigned date
started date
completed date
SELECT prj.prj_number AS number
, prj.prj_name AS name
, prj.prj_descrip AS description
, prj.prj_owner_username AS owner
, prj.prj_username AS assigned_to
, prj.prj_so AS sales_orders
, prj.prj_wo AS work_orders
, prj.prj_po AS purchase_orders
, CASE WHEN 
(prj.prj_status = 'P'::bpchar) THEN 'Concept'::text WHEN 
(prj.prj_status = 'O'::bpchar) THEN 'In-Process'::text WHEN 
(prj.prj_status = 'C'::bpchar) THEN 'Closed'::text ELSE 'Error'::text END AS status
, prj.prj_due_date AS due
, prj.prj_assigned_date AS assigned
, prj.prj_start_date AS started
, prj.prj_completed_date AS completed 
FROM prj;

Index - Schema api


View: api.projectcomment

Project Comment

api.projectcomment Structure
F-Key Name Type Description
project_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (prj.prj_number)::character varying AS project_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM prj
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'J'::text)
         AND (comment.comment_source_id = prj.prj_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.prospect

Prospect

api.prospect Structure
F-Key Name Type Description
prospect_number character varying
prospect_name text
active boolean
sales_rep text
site_code text
default_tax_zone text
notes text
contact_number text
contact_honorific text
contact_first text
contact_middle text
contact_last text
contact_suffix text
contact_job_title text
contact_voice text
contact_alternate text
contact_fax text
contact_email text
contact_web text
contact_change text
contact_address_number text
contact_address1 text
contact_address2 text
contact_address3 text
contact_city text
contact_state text
contact_postalcode text
contact_country text
contact_address_change text
SELECT (prospect.prospect_number)::character varying AS prospect_number
, prospect.prospect_name
, prospect.prospect_active AS active
, salesrep.salesrep_number AS sales_rep
, whsinfo.warehous_code AS site_code
, taxzone.taxzone_code AS default_tax_zone
, prospect.prospect_comments AS notes
, cntct.cntct_number AS contact_number
, cntct.cntct_honorific AS contact_honorific
, cntct.cntct_first_name AS contact_first
, cntct.cntct_middle AS contact_middle
, cntct.cntct_last_name AS contact_last
, cntct.cntct_suffix AS contact_suffix
, cntct.cntct_title AS contact_job_title
, cntct.cntct_phone AS contact_voice
, cntct.cntct_phone2 AS contact_alternate
, cntct.cntct_fax AS contact_fax
, cntct.cntct_email AS contact_email
, cntct.cntct_webaddr AS contact_web
,''::text AS contact_change
, addr.addr_number AS contact_address_number
, addr.addr_line1 AS contact_address1
, addr.addr_line2 AS contact_address2
, addr.addr_line3 AS contact_address3
, addr.addr_city AS contact_city
, addr.addr_state AS contact_state
, addr.addr_postalcode AS contact_postalcode
, addr.addr_country AS contact_country
,''::text AS contact_address_change 
FROM (
     (
           (
                 (
                       (prospect 
                     LEFT JOIN cntct 
                            ON (
                                   (prospect.prospect_cntct_id = cntct.cntct_id)
                             )
                       )
               LEFT JOIN addr 
                      ON (
                             (cntct.cntct_addr_id = addr.addr_id)
                       )
                 )
         LEFT JOIN taxzone 
                ON (
                       (prospect.prospect_taxzone_id = taxzone.taxzone_id)
                 )
           )
   LEFT JOIN salesrep 
          ON (
                 (prospect.prospect_salesrep_id = salesrep.salesrep_id)
           )
     )
LEFT JOIN whsinfo 
    ON (
           (prospect.prospect_warehous_id = whsinfo.warehous_id)
     )
);

Index - Schema api


View: api.purchaseline

Purchase Order Line

api.purchaseline Structure
F-Key Name Type Description
order_number character varying
line_number integer
item_number text
site text
expense_category text
qty_ordered numeric(18,6)
unit_price numeric(16,6)
freight numeric(16,4)
due_date date
project_number text
vend_item_number text
vendor_description text
manufacturer_name text
manufacturer_item_number text
manufacturer_description text
notes text
bill_of_materials_revision text
bill_of_operations_revision text
sales_order_number text
work_order_number text
SELECT (pohead.pohead_number)::character varying AS order_number
, poitem.poitem_linenumber AS line_number
, item.item_number
, whsinfo.warehous_code AS site
, expcat.expcat_code AS expense_category
, poitem.poitem_qty_ordered AS qty_ordered
, poitem.poitem_unitprice AS unit_price
, poitem.poitem_freight AS freight
, poitem.poitem_duedate AS due_date
, prj.prj_number AS project_number
, poitem.poitem_vend_item_number AS vend_item_number
, poitem.poitem_vend_item_descrip AS vendor_description
, poitem.poitem_manuf_name AS manufacturer_name
, poitem.poitem_manuf_item_number AS manufacturer_item_number
, poitem.poitem_manuf_item_descrip AS manufacturer_description
, poitem.poitem_comments AS notes
, formatrevnumber
('BOM'::text
     , poitem.poitem_bom_rev_id
) AS bill_of_materials_revision
, formatrevnumber
('BOO'::text
     , poitem.poitem_boo_rev_id
) AS bill_of_operations_revision
, formatsonumber
(coitem.coitem_id) AS sales_order_number
, formatwonumber
(womatl.womatl_wo_id) AS work_order_number 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (pohead 
                                            JOIN poitem 
                                              ON (
                                                     (pohead.pohead_id = poitem.poitem_pohead_id)
                                               )
                                         )
                                 LEFT JOIN prj 
                                        ON (
                                               (poitem.poitem_prj_id = prj.prj_id)
                                         )
                                   )
                           LEFT JOIN expcat 
                                  ON (
                                         (poitem.poitem_expcat_id = expcat.expcat_id)
                                   )
                             )
                     LEFT JOIN itemsite 
                            ON (
                                   (poitem.poitem_itemsite_id = itemsite.itemsite_id)
                             )
                       )
               LEFT JOIN item 
                      ON (
                             (itemsite.itemsite_item_id = item.item_id)
                       )
                 )
         LEFT JOIN whsinfo 
                ON (
                       (itemsite.itemsite_warehous_id = whsinfo.warehous_id)
                 )
           )
   LEFT JOIN coitem 
          ON (
                 (
                       (coitem.coitem_id = poitem.poitem_order_id)
                     AND (poitem.poitem_order_type = 'S'::bpchar)
                 )
           )
     )
LEFT JOIN womatl 
    ON (
           (
                 (womatl.womatl_id = poitem.poitem_order_id)
               AND (poitem.poitem_order_type = 'W'::bpchar)
           )
     )
)
ORDER BY pohead.pohead_number
, poitem.poitem_linenumber;

Index - Schema api


View: api.purchaselinechar

Purchase Order Line Item Characteristic

api.purchaselinechar Structure
F-Key Name Type Description
order_number character varying
line_number integer
characteristic text
value text
SELECT (data.order_number)::character varying AS order_number
, data.line_number
, data.characteristic
, COALESCE
(pi.charass_value
     , i3.charass_value
) AS value 
FROM (
     (
           (
                 (
                       (
                        SELECT DISTINCT "char".char_id
                             , poitem.poitem_id
                             , poitem.poitem_itemsite_id
                             , pohead.pohead_number AS order_number
                             , poitem.poitem_linenumber AS line_number
                             ,"char".char_name AS characteristic 
                          FROM pohead
                             , poitem
                             , itemsite
                             , item
                             , charass
                             ,"char"
                         WHERE (
                                   (
                                         (
                                               (
                                                     (
                                                           (pohead.pohead_id = poitem.poitem_pohead_id)
                                                         AND (poitem.poitem_itemsite_id = itemsite.itemsite_id)
                                                     )
                                                   AND (itemsite.itemsite_item_id = item.item_id)
                                               )
                                             AND (charass.charass_char_id = "char".char_id)
                                         )
                                       AND (charass.charass_target_type = 'I'::text)
                                   )
                                 AND (charass.charass_target_id = item.item_id)
                             )
                       ) data 
               LEFT JOIN charass pi 
                      ON (
                             (
                                   (
                                         (data.poitem_id = pi.charass_target_id)
                                       AND ('PI'::text = pi.charass_target_type)
                                   )
                                 AND (pi.charass_char_id = data.char_id)
                             )
                       )
                 )
         LEFT JOIN itemsite i1 
                ON (
                       (data.poitem_itemsite_id = i1.itemsite_id)
                 )
           )
   LEFT JOIN item i2 
          ON (
                 (i1.itemsite_item_id = i2.item_id)
           )
     )
LEFT JOIN charass i3 
    ON (
           (
                 (
                       (
                             (i2.item_id = i3.charass_target_id)
                           AND ('I'::text = i3.charass_target_type)
                       )
                     AND (i3.charass_char_id = data.char_id)
                 )
               AND i3.charass_default
           )
     )
)
ORDER BY (data.order_number)::character varying
, data.line_number
, data.characteristic;

Index - Schema api


View: api.purchaselinecomment

Purchase Order Line Item Comment

api.purchaselinecomment Structure
F-Key Name Type Description
order_number character varying
line_number integer
type text
date timestamp with time zone
username text
text text
SELECT (pohead.pohead_number)::character varying AS order_number
, poitem.poitem_linenumber AS line_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM pohead
, poitem
, cmnttype
, comment 
WHERE (
     (
           (
                 (pohead.pohead_id = poitem.poitem_pohead_id)
               AND (comment.comment_source = 'PI'::text)
           )
         AND (comment.comment_source_id = poitem.poitem_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
)
ORDER BY pohead.pohead_number
, poitem.poitem_linenumber
, comment.comment_date DESC;

Index - Schema api


View: api.purchaseorder

Purchase Order

api.purchaseorder Structure
F-Key Name Type Description
order_number character varying
order_date date
terms text
tax_zone text
receiving_site text
purchasing_agent text
vendor_number text
alt_address text
fob text
ship_via text
currency character varying(3)
tax numeric
freight numeric(16,2)
notes text
dropship boolean
vend_contact_number text
vend_cntct_honorific text
vend_cntct_first_name text
vend_cntct_middle text
vend_cntct_last_name text
vend_cntct_suffix text
vend_cntct_phone text
vend_cntct_title text
vend_cntct_fax text
vend_cntct_email text
vendaddress1 text
vendaddress2 text
vendaddress3 text
vendcity text
vendstate text
vendzipcode text
vendcountry text
shipto_contact_number text
shipto_cntct_honorific text
shipto_cntct_first_name text
shipto_cntct_middle text
shipto_cntct_last_name text
shipto_cntct_suffix text
shipto_cntct_phone text
shipto_cntct_title text
shipto_cntct_fax text
shipto_cntct_email text
shiptoaddress_number text
shiptoaddress1 text
shiptoaddress2 text
shiptoaddress3 text
shiptocity text
shiptostate text
shiptozipcode text
shiptocountry text
sales_order_number text
SELECT (pohead.pohead_number)::character varying AS order_number
, pohead.pohead_orderdate AS order_date
, terms.terms_code AS terms
, taxzone.taxzone_code AS tax_zone
, whsinfo.warehous_code AS receiving_site
, pohead.pohead_agent_username AS purchasing_agent
, vendinfo.vend_number AS vendor_number
, COALESCE
(ua.vendaddr_code
     ,'MAIN'::text
) AS alt_address
, pohead.pohead_fob AS fob
, pohead.pohead_shipvia AS ship_via
, curr_symbol.curr_abbr AS currency
, (
SELECT COALESCE
     (sum
           (data.tax)
           , 0.00
     ) AS tax 
  FROM (
      SELECT round
           (sum
                 (calculatetaxdetailsummary.taxdetail_tax)
                 , 2
           ) AS tax 
        FROM (tax 
              JOIN calculatetaxdetailsummary
                 ('PO'::text
                       , pohead.pohead_id
                       ,'T'::text
                 ) calculatetaxdetailsummary
                 (taxdetail_tax_id
                       , taxdetail_tax_code
                       , taxdetail_tax_descrip
                       , taxdetail_tax_basis_tax_id
                       , taxdetail_taxrate_percent
                       , taxdetail_taxrate_amount
                       , taxdetail_level
                       , taxdetail_taxclass_id
                       , taxdetail_taxclass_code
                       , taxdetail_taxclass_sequence
                       , taxdetail_tax
                       , taxdetail_curr_id
                       , taxdetail_curr_abbr
                 )
                ON (
                       (calculatetaxdetailsummary.taxdetail_tax_id = tax.tax_id)
                 )
           )
    GROUP BY tax.tax_id
     ) data
) AS tax
, pohead.pohead_freight AS freight
, pohead.pohead_comments AS notes
, pohead.pohead_dropship AS dropship
, vc.cntct_number AS vend_contact_number
, pohead.pohead_vend_cntct_honorific AS vend_cntct_honorific
, pohead.pohead_vend_cntct_first_name AS vend_cntct_first_name
, pohead.pohead_vend_cntct_middle AS vend_cntct_middle
, pohead.pohead_vend_cntct_last_name AS vend_cntct_last_name
, pohead.pohead_vend_cntct_suffix AS vend_cntct_suffix
, pohead.pohead_vend_cntct_phone AS vend_cntct_phone
, pohead.pohead_vend_cntct_title AS vend_cntct_title
, pohead.pohead_vend_cntct_fax AS vend_cntct_fax
, pohead.pohead_vend_cntct_email AS vend_cntct_email
, pohead.pohead_vendaddress1 AS vendaddress1
, pohead.pohead_vendaddress2 AS vendaddress2
, pohead.pohead_vendaddress3 AS vendaddress3
, pohead.pohead_vendcity AS vendcity
, pohead.pohead_vendstate AS vendstate
, pohead.pohead_vendzipcode AS vendzipcode
, pohead.pohead_vendcountry AS vendcountry
, sc.cntct_number AS shipto_contact_number
, pohead.pohead_shipto_cntct_honorific AS shipto_cntct_honorific
, pohead.pohead_shipto_cntct_first_name AS shipto_cntct_first_name
, pohead.pohead_shipto_cntct_middle AS shipto_cntct_middle
, pohead.pohead_shipto_cntct_last_name AS shipto_cntct_last_name
, pohead.pohead_shipto_cntct_suffix AS shipto_cntct_suffix
, pohead.pohead_shipto_cntct_phone AS shipto_cntct_phone
, pohead.pohead_shipto_cntct_title AS shipto_cntct_title
, pohead.pohead_shipto_cntct_fax AS shipto_cntct_fax
, pohead.pohead_shipto_cntct_email AS shipto_cntct_email
, addr.addr_number AS shiptoaddress_number
, pohead.pohead_shiptoaddress1 AS shiptoaddress1
, pohead.pohead_shiptoaddress2 AS shiptoaddress2
, pohead.pohead_shiptoaddress3 AS shiptoaddress3
, pohead.pohead_shiptocity AS shiptocity
, pohead.pohead_shiptostate AS shiptostate
, pohead.pohead_shiptozipcode AS shiptozipcode
, pohead.pohead_shiptocountry AS shiptocountry
, cohead.cohead_number AS sales_order_number 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (
                                                     (pohead 
                                                   LEFT JOIN cntct vc 
                                                          ON (
                                                                 (pohead.pohead_vend_cntct_id = vc.cntct_id)
                                                           )
                                                     )
                                             LEFT JOIN cntct sc 
                                                    ON (
                                                           (pohead.pohead_shipto_cntct_id = sc.cntct_id)
                                                     )
                                               )
                                       LEFT JOIN addr 
                                              ON (
                                                     (pohead.pohead_shiptoaddress_id = addr.addr_id)
                                               )
                                         )
                                 LEFT JOIN terms 
                                        ON (
                                               (pohead.pohead_terms_id = terms.terms_id)
                                         )
                                   )
                           LEFT JOIN taxzone 
                                  ON (
                                         (pohead.pohead_taxzone_id = taxzone.taxzone_id)
                                   )
                             )
                     LEFT JOIN whsinfo 
                            ON (
                                   (pohead.pohead_warehous_id = whsinfo.warehous_id)
                             )
                       )
               LEFT JOIN vendaddrinfo ua 
                      ON (
                             (pohead.pohead_vendaddr_id = ua.vendaddr_id)
                       )
                 )
         LEFT JOIN cohead 
                ON (
                       (pohead.pohead_cohead_id = cohead.cohead_id)
                 )
           )
        JOIN vendinfo 
          ON (
                 (pohead.pohead_vend_id = vendinfo.vend_id)
           )
     )
  JOIN curr_symbol 
    ON (
           (pohead.pohead_curr_id = curr_symbol.curr_id)
     )
)
ORDER BY pohead.pohead_number;

Index - Schema api


View: api.purchaseordercomment

Purchase Order Comment

api.purchaseordercomment Structure
F-Key Name Type Description
order_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (pohead.pohead_number)::character varying AS order_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM pohead
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'P'::text)
         AND (comment.comment_source_id = pohead.pohead_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.quote

Quote

api.quote Structure
F-Key Name Type Description
quote_number character varying
site text
quote_date date
pack_date date
originated_by text
sale_type text
sales_rep text
commission numeric(16,4)
tax_zone text
tax_type text
terms text
project_number text
customer_number text
billto_name text
billto_address1 text
billto_address2 text
billto_address3 text
billto_city text
billto_state text
billto_postal_code text
billto_country text
shipto_number text
shipto_name text
shipto_phone text
shipto_address1 text
shipto_address2 text
shipto_address3 text
shipto_city text
shipto_state text
shipto_postal_code text
shipto_country text
shipto_shipzone text
cust_po_number text
fob text
ship_via text
currency character varying(3)
misc_charge_description text
misc_account_number text
misc_charge numeric(16,4)
freight numeric(16,4)
order_notes text
shipping_notes text
add_to_packing_list_batch boolean
expire_date date
status text
SELECT (quhead.quhead_number)::character varying AS quote_number
, whsinfo.warehous_code AS site
, quhead.quhead_quotedate AS quote_date
, quhead.quhead_packdate AS pack_date
, CASE WHEN 
(quhead.quhead_origin = 'C'::bpchar) THEN 'Customer'::text WHEN 
(quhead.quhead_origin = 'I'::bpchar) THEN 'Internet'::text WHEN 
(quhead.quhead_origin = 'S'::bpchar) THEN 'Sales Rep.'::text ELSE 'Error'::text END AS originated_by
, saletype.saletype_code AS sale_type
, salesrep.salesrep_number AS sales_rep
, quhead.quhead_commission AS commission
, taxzone.taxzone_code AS tax_zone
, taxtype.taxtype_name AS tax_type
, terms.terms_code AS terms
, prj.prj_number AS project_number
, COALESCE
(custinfo.cust_number
     , prospect.prospect_number
) AS customer_number
, quhead.quhead_billtoname AS billto_name
, quhead.quhead_billtoaddress1 AS billto_address1
, quhead.quhead_billtoaddress2 AS billto_address2
, quhead.quhead_billtoaddress3 AS billto_address3
, quhead.quhead_billtocity AS billto_city
, quhead.quhead_billtostate AS billto_state
, quhead.quhead_billtozip AS billto_postal_code
, quhead.quhead_billtocountry AS billto_country
, shiptoinfo.shipto_num AS shipto_number
, quhead.quhead_shiptoname AS shipto_name
, quhead.quhead_shiptophone AS shipto_phone
, quhead.quhead_shiptoaddress1 AS shipto_address1
, quhead.quhead_shiptoaddress2 AS shipto_address2
, quhead.quhead_shiptoaddress3 AS shipto_address3
, quhead.quhead_shiptocity AS shipto_city
, quhead.quhead_shiptostate AS shipto_state
, quhead.quhead_shiptozipcode AS shipto_postal_code
, quhead.quhead_shiptocountry AS shipto_country
, shipzone.shipzone_name AS shipto_shipzone
, quhead.quhead_custponumber AS cust_po_number
, quhead.quhead_fob AS fob
, quhead.quhead_shipvia AS ship_via
, curr_symbol.curr_abbr AS currency
, quhead.quhead_misc_descrip AS misc_charge_description
, CASE WHEN 
(quhead.quhead_misc_accnt_id IS NULL) THEN NULL::text ELSE formatglaccount
(quhead.quhead_misc_accnt_id) END AS misc_account_number
, quhead.quhead_misc AS misc_charge
, quhead.quhead_freight AS freight
, quhead.quhead_ordercomments AS order_notes
, quhead.quhead_shipcomments AS shipping_notes
, false AS add_to_packing_list_batch
, quhead.quhead_expire AS expire_date
, CASE WHEN 
(quhead.quhead_status = 'C'::text) THEN 'Converted'::text ELSE 'Open'::text END AS status 
FROM curr_symbol
, (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (
                                                     (
                                                           (quhead 
                                                         LEFT JOIN whsinfo 
                                                                ON (
                                                                       (quhead.quhead_warehous_id = whsinfo.warehous_id)
                                                                 )
                                                           )
                                                   LEFT JOIN prj 
                                                          ON (
                                                                 (quhead.quhead_prj_id = prj.prj_id)
                                                           )
                                                     )
                                             LEFT JOIN shiptoinfo 
                                                    ON (
                                                           (quhead.quhead_shipto_id = shiptoinfo.shipto_id)
                                                     )
                                               )
                                       LEFT JOIN taxzone 
                                              ON (
                                                     (quhead.quhead_taxzone_id = taxzone.taxzone_id)
                                               )
                                         )
                                 LEFT JOIN taxtype 
                                        ON (
                                               (quhead.quhead_taxtype_id = taxtype.taxtype_id)
                                         )
                                   )
                           LEFT JOIN custinfo 
                                  ON (
                                         (quhead.quhead_cust_id = custinfo.cust_id)
                                   )
                             )
                     LEFT JOIN prospect 
                            ON (
                                   (quhead.quhead_cust_id = prospect.prospect_id)
                             )
                       )
               LEFT JOIN salesrep 
                      ON (
                             (quhead.quhead_salesrep_id = salesrep.salesrep_id)
                       )
                 )
         LEFT JOIN terms 
                ON (
                       (quhead.quhead_terms_id = terms.terms_id)
                 )
           )
   LEFT JOIN saletype 
          ON (
                 (quhead.quhead_saletype_id = saletype.saletype_id)
           )
     )
LEFT JOIN shipzone 
    ON (
           (quhead.quhead_shipzone_id = shipzone.shipzone_id)
     )
)
WHERE (quhead.quhead_curr_id = curr_symbol.curr_id);

Index - Schema api


View: api.quotecomment

Quote Comment

api.quotecomment Structure
F-Key Name Type Description
quote_number text
type text
date timestamp with time zone
username text
text text
SELECT quhead.quhead_number AS quote_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM quhead
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'Q'::text)
         AND (comment.comment_source_id = quhead.quhead_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.quoteline

Quote Line Item

api.quoteline Structure
F-Key Name Type Description
quote_number text
line_number integer
item_number text
customer_pn text
sold_from_site text
qty_ordered numeric(18,6)
qty_uom text
net_unit_price numeric(16,4)
price_uom text
scheduled_date date
tax_type text
discount_pct_from_list text
create_order boolean
supplying_site text
overwrite_po_price numeric(16,6)
notes text
SELECT quhead.quhead_number AS quote_number
, quitem.quitem_linenumber AS line_number
, l.item_number
, quitem.quitem_custpn AS customer_pn
, i.warehous_code AS sold_from_site
, quitem.quitem_qtyord AS qty_ordered
, q.uom_name AS qty_uom
, quitem.quitem_price AS net_unit_price
, p.uom_name AS price_uom
, quitem.quitem_scheddate AS scheduled_date
, COALESCE
(
     (
      SELECT taxtype.taxtype_name 
        FROM taxtype 
       WHERE (taxtype.taxtype_id = getitemtaxtype
                 (l.item_id
                       , quhead.quhead_taxzone_id
                 )
           )
     )
     ,'None'::text
) AS tax_type
, CASE WHEN 
(quitem.quitem_price = 
     (0)::numeric
) THEN '100'::text WHEN 
(quitem.quitem_custprice = 
     (0)::numeric
) THEN 'N/A'::text ELSE 
(round
     (
           (
                 (
                       (1)::numeric - 
                       (quitem.quitem_price / quitem.quitem_custprice)
                 ) * 
                 (100)::numeric
           )
           , 4
     )
)::text END AS discount_pct_from_list
, quitem.quitem_createorder AS create_order
, s.warehous_code AS supplying_site
, quitem.quitem_prcost AS overwrite_po_price
, quitem.quitem_memo AS notes 
FROM quhead
, uom q
, uom p
, (quitem 
LEFT JOIN whsinfo s 
    ON (
           (quitem.quitem_order_warehous_id = s.warehous_id)
     )
)
, itemsite il
, item l
, whsinfo i 
WHERE (
     (
           (
                 (
                       (
                             (quhead.quhead_id = quitem.quitem_quhead_id)
                           AND (quitem.quitem_itemsite_id = il.itemsite_id)
                       )
                     AND (il.itemsite_item_id = l.item_id)
                 )
               AND (il.itemsite_warehous_id = i.warehous_id)
           )
         AND (quitem.quitem_qty_uom_id = q.uom_id)
     )
   AND (quitem.quitem_price_uom_id = p.uom_id)
)
ORDER BY quhead.quhead_number
, quitem.quitem_linenumber;

Index - Schema api


View: api.quotelinechar

Quote Line Item Characteristics

api.quotelinechar Structure
F-Key Name Type Description
quote_number text
line_number integer
characteristic text
value text
SELECT DISTINCT quhead.quhead_number AS quote_number
, quitem.quitem_linenumber AS line_number
,"char".char_name AS characteristic
, COALESCE
(
     (
      SELECT b.charass_value 
        FROM charass b 
       WHERE (
                 (
                       (b.charass_target_type = 'QI'::text)
                     AND (b.charass_target_id = quitem.quitem_id)
                 )
               AND (b.charass_char_id = "char".char_id)
           )
     )
     , (
      SELECT c.charass_value 
        FROM charass c 
       WHERE (
                 (
                       (
                             (c.charass_target_type = 'I'::text)
                           AND (c.charass_target_id = item.item_id)
                       )
                     AND c.charass_default
                 )
               AND (c.charass_char_id = "char".char_id)
           ) LIMIT 1
     )
) AS value 
FROM quhead
, quitem
, itemsite
, item
, charass a
,"char"
WHERE (
     (
           (
                 (
                       (
                             (quhead.quhead_id = quitem.quitem_quhead_id)
                           AND (quitem.quitem_itemsite_id = itemsite.itemsite_id)
                       )
                     AND (itemsite.itemsite_item_id = item.item_id)
                 )
               AND (a.charass_char_id = "char".char_id)
           )
         AND (a.charass_target_type = 'I'::text)
     )
   AND (a.charass_target_id = item.item_id)
)
ORDER BY quhead.quhead_number
, quitem.quitem_linenumber
,"char".char_name;

Index - Schema api


View: api.quotelinecomment

Quote Line Item Comment

api.quotelinecomment Structure
F-Key Name Type Description
quote_number text
line_number integer
type text
date timestamp with time zone
username text
text text
SELECT quhead.quhead_number AS quote_number
, quitem.quitem_linenumber AS line_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM quhead
, quitem
, cmnttype
, comment 
WHERE (
     (
           (
                 (quhead.quhead_id = quitem.quitem_quhead_id)
               AND (comment.comment_source = 'QI'::text)
           )
         AND (comment.comment_source_id = quitem.quitem_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
)
ORDER BY quhead.quhead_number
, quitem.quitem_linenumber
, comment.comment_date DESC;

Index - Schema api


View: api.salescredit

Payments (credit memos) pre-applied to sales orders

api.salescredit Structure
F-Key Name Type Description
customer_number text
cm_number text
so_number text
amount numeric(16,4)
currency character varying(3)
SELECT custinfo.cust_number AS customer_number
, aropen.aropen_docnumber AS cm_number
, cohead.cohead_number AS so_number
, (aropenalloc.aropenalloc_amount)::numeric
(16
     ,4
) AS amount
, curr.curr_abbr AS currency 
FROM (
     (
           (
                 (aropenalloc 
               LEFT JOIN aropen 
                      ON (
                             (aropen.aropen_id = aropenalloc.aropenalloc_aropen_id)
                       )
                 )
         LEFT JOIN custinfo 
                ON (
                       (custinfo.cust_id = aropen.aropen_cust_id)
                 )
           )
   LEFT JOIN cohead 
          ON (
                 (
                       (aropenalloc.aropenalloc_doctype = 'S'::bpchar)
                     AND (cohead.cohead_id = aropenalloc.aropenalloc_doc_id)
                 )
           )
     )
LEFT JOIN curr_symbol curr 
    ON (
           (curr.curr_id = aropenalloc.aropenalloc_curr_id)
     )
)
WHERE (aropenalloc.aropenalloc_doctype = 'S'::bpchar);

Index - Schema api


View: api.saleshistory

Sales History

api.saleshistory Structure
F-Key Name Type Description
customer_number text
item_number text
site_code text
ship_date date
ship_via text
order_number text
purchase_order_number text
order_date date
invoice_number text
invoice_date date
quantity_shipped numeric(18,6)
unit_price numeric(16,4)
shipto_number text
sales_rep text
due_date date
promise_date date
imported boolean
billto_name text
billto_address1 text
billto_address2 text
billto_address3 text
billto_city text
billto_state text
billto_zip text
shipto_name text
shipto_address1 text
shipto_address2 text
shipto_address3 text
shipto_city text
shipto_state text
shipto_zip text
commission numeric(16,4)
commission_paid boolean
unit_cost numeric(18,6)
misc_type text
misc_description text
misc_info text
tax_zone text
tax_type text
document_type text
currency character varying(3)
gl_sequence integer
tax numeric
SELECT custinfo.cust_number AS customer_number
, item.item_number
, whsinfo.warehous_code AS site_code
, cohist.cohist_shipdate AS ship_date
, cohist.cohist_shipvia AS ship_via
, cohist.cohist_ordernumber AS order_number
, cohist.cohist_ponumber AS purchase_order_number
, cohist.cohist_orderdate AS order_date
, cohist.cohist_invcnumber AS invoice_number
, cohist.cohist_invcdate AS invoice_date
, cohist.cohist_qtyshipped AS quantity_shipped
, cohist.cohist_unitprice AS unit_price
, shiptoinfo.shipto_num AS shipto_number
, salesrep.salesrep_number AS sales_rep
, cohist.cohist_duedate AS due_date
, cohist.cohist_promisedate AS promise_date
, cohist.cohist_imported AS imported
, cohist.cohist_billtoname AS billto_name
, cohist.cohist_billtoaddress1 AS billto_address1
, cohist.cohist_billtoaddress2 AS billto_address2
, cohist.cohist_billtoaddress3 AS billto_address3
, cohist.cohist_billtocity AS billto_city
, cohist.cohist_billtostate AS billto_state
, cohist.cohist_billtozip AS billto_zip
, cohist.cohist_shiptoname AS shipto_name
, cohist.cohist_shiptoaddress1 AS shipto_address1
, cohist.cohist_shiptoaddress2 AS shipto_address2
, cohist.cohist_shiptoaddress3 AS shipto_address3
, cohist.cohist_shiptocity AS shipto_city
, cohist.cohist_shiptostate AS shipto_state
, cohist.cohist_shiptozip AS shipto_zip
, cohist.cohist_commission AS commission
, cohist.cohist_commissionpaid AS commission_paid
, cohist.cohist_unitcost AS unit_cost
, CASE WHEN 
(cohist.cohist_misc_type IS NULL) THEN ''::text WHEN 
(cohist.cohist_misc_type = 'M'::bpchar) THEN 'Misc. Charge'::text WHEN 
(cohist.cohist_misc_type = 'F'::bpchar) THEN 'Freight'::text ELSE 'Unknown'::text END AS misc_type
, cohist.cohist_misc_descrip AS misc_description
, CASE WHEN 
(cohist.cohist_misc_id IS NULL) THEN ''::text WHEN 
(cohist.cohist_misc_type = 'M'::bpchar) THEN formatglaccount
(cohist.cohist_misc_id) ELSE 'Unknown'::text END AS misc_info
, taxzone.taxzone_code AS tax_zone
, taxtype.taxtype_name AS tax_type
, CASE WHEN 
(cohist.cohist_doctype = 'I'::text) THEN 'Invoice'::text WHEN 
(cohist.cohist_doctype = 'C'::text) THEN 'Credit Memo'::text ELSE 'Unknown'::text END AS document_type
, curr_symbol.curr_abbr AS currency
, cohist.cohist_sequence AS gl_sequence
, (
SELECT sum
     (cohisttax.taxhist_tax) AS sum 
  FROM cohisttax 
 WHERE (cohisttax.taxhist_parent_id = cohist.cohist_id)
) AS tax 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (cohist 
                                             LEFT JOIN custinfo 
                                                    ON (
                                                           (cohist.cohist_cust_id = custinfo.cust_id)
                                                     )
                                               )
                                       LEFT JOIN shiptoinfo 
                                              ON (
                                                     (cohist.cohist_shipto_id = shiptoinfo.shipto_id)
                                               )
                                         )
                                 LEFT JOIN taxzone 
                                        ON (
                                               (cohist.cohist_taxzone_id = taxzone.taxzone_id)
                                         )
                                   )
                           LEFT JOIN taxtype 
                                  ON (
                                         (cohist.cohist_taxtype_id = taxtype.taxtype_id)
                                   )
                             )
                     LEFT JOIN salesrep 
                            ON (
                                   (cohist.cohist_salesrep_id = salesrep.salesrep_id)
                             )
                       )
               LEFT JOIN itemsite 
                      ON (
                             (cohist.cohist_itemsite_id = itemsite.itemsite_id)
                       )
                 )
         LEFT JOIN item 
                ON (
                       (itemsite.itemsite_item_id = item.item_id)
                 )
           )
   LEFT JOIN whsinfo 
          ON (
                 (itemsite.itemsite_warehous_id = whsinfo.warehous_id)
           )
     )
LEFT JOIN curr_symbol 
    ON (
           (cohist.cohist_curr_id = curr_symbol.curr_id)
     )
);

Index - Schema api


View: api.salesline

Sales Order Line Item

api.salesline Structure
F-Key Name Type Description
order_number character varying
line_number character varying
item_number text
customer_pn text
substitute_for text
sold_from_site text
status character(1)
qty_ordered numeric(18,6)
qty_uom text
net_unit_price numeric(16,4)
price_uom text
scheduled_date date
promise_date date
warranty boolean
tax_type text
discount_pct_from_list text
create_order boolean
create_po text
overwrite_po_price numeric(16,6)
notes text
alternate_cos_account text
alternate_rev_account text
SELECT (cohead.cohead_number)::character varying AS order_number
, (formatsolinenumber
     (coitem.coitem_id)
)::character varying AS line_number
, l.item_number
, coitem.coitem_custpn AS customer_pn
, s.item_number AS substitute_for
, whsinfo.warehous_code AS sold_from_site
, coitem.coitem_status AS status
, coitem.coitem_qtyord AS qty_ordered
, q.uom_name AS qty_uom
, coitem.coitem_price AS net_unit_price
, p.uom_name AS price_uom
, coitem.coitem_scheddate AS scheduled_date
, coitem.coitem_promdate AS promise_date
, coitem.coitem_warranty AS warranty
, COALESCE
(
     (
      SELECT taxtype.taxtype_name 
        FROM taxtype 
       WHERE (taxtype.taxtype_id = getitemtaxtype
                 (l.item_id
                       , cohead.cohead_taxzone_id
                 )
           )
     )
     ,'None'::text
) AS tax_type
, CASE WHEN 
(coitem.coitem_price = 
     (0)::numeric
) THEN '100'::text WHEN 
(coitem.coitem_custprice = 
     (0)::numeric
) THEN 'N/A'::text ELSE 
(round
     (
           (
                 (
                       (1)::numeric - 
                       (coitem.coitem_price / coitem.coitem_custprice)
                 ) * 
                 (100)::numeric
           )
           , 4
     )
)::text END AS discount_pct_from_list
, CASE WHEN 
(coitem.coitem_order_id = 
     (-1)
) THEN false ELSE true END AS create_order
, CASE WHEN 
(coitem.coitem_order_id = 
     (-1)
) THEN ''::text ELSE 
(
     (pohead.pohead_number || '-'::text) || poitem.poitem_linenumber
) END AS create_po
, coitem.coitem_prcost AS overwrite_po_price
, coitem.coitem_memo AS notes
, CASE WHEN 
(coitem.coitem_cos_accnt_id IS NOT NULL) THEN formatglaccount
(coitem.coitem_cos_accnt_id) ELSE NULL::text END AS alternate_cos_account
, CASE WHEN 
(coitem.coitem_rev_accnt_id IS NOT NULL) THEN formatglaccount
(coitem.coitem_rev_accnt_id) ELSE NULL::text END AS alternate_rev_account 
FROM cohead
, (
     (
           (coitem 
         LEFT JOIN itemsite isb 
                ON (
                       (coitem.coitem_substitute_item_id = isb.itemsite_id)
                 )
           )
   LEFT JOIN item s 
          ON (
                 (isb.itemsite_item_id = s.item_id)
           )
     )
LEFT JOIN (poitem 
        JOIN pohead 
          ON (
                 (poitem.poitem_pohead_id = pohead.pohead_id)
           )
     )
    ON (
           (poitem.poitem_id = coitem.coitem_order_id)
     )
)
, itemsite il
, item l
, whsinfo
, uom q
, uom p 
WHERE (
     (
           (
                 (
                       (
                             (cohead.cohead_id = coitem.coitem_cohead_id)
                           AND (coitem.coitem_itemsite_id = il.itemsite_id)
                       )
                     AND (il.itemsite_item_id = l.item_id)
                 )
               AND (il.itemsite_warehous_id = whsinfo.warehous_id)
           )
         AND (coitem.coitem_qty_uom_id = q.uom_id)
     )
   AND (coitem.coitem_price_uom_id = p.uom_id)
)
ORDER BY cohead.cohead_number
, coitem.coitem_linenumber
, coitem.coitem_subnumber;

Index - Schema api


View: api.saleslinechar

Sales Order Line Item Characteristic

api.saleslinechar Structure
F-Key Name Type Description
order_number character varying
line_number text
characteristic text
value text
price numeric(16,4)
SELECT (data.order_number)::character varying AS order_number
, data.line_number
, data.characteristic
, COALESCE
(si.charass_value
     , i3.charass_value
) AS value
, (COALESCE
     (si.charass_price
           , itemcharprice
           (data.item_id
                 , data.char_id
                 , COALESCE
                 (si.charass_value
                       , i3.charass_value
                 )
                 , data.cohead_cust_id
                 , data.cohead_shipto_id
                 , data.coitem_qtyord
                 , data.cohead_curr_id
                 , data.cohead_orderdate
           )
           , (0)::numeric
     )
)::numeric
(16
     ,4
) AS price 
FROM (
     (
           (
                 (
                       (
                        SELECT DISTINCT cohead.cohead_cust_id
                             , cohead.cohead_shipto_id
                             , cohead.cohead_curr_id
                             , cohead.cohead_orderdate
                             , coitem.coitem_id
                             , coitem.coitem_itemsite_id
                             , coitem.coitem_qtyord
                             ,"char".char_id
                             , item.item_id
                             , cohead.cohead_number AS order_number
                             , CASE WHEN 
                             (coitem.coitem_subnumber = 0) THEN 
                             (
                                   (coitem.coitem_linenumber)::character varying
                             )::text ELSE 
                             (
                                   (
                                         (
                                               (coitem.coitem_linenumber)::character varying
                                         )::text || 
                                         ('.'::character varying)::text
                                   ) || 
                                   (
                                         (coitem.coitem_subnumber)::character varying
                                   )::text
                             ) END AS line_number
                             ,"char".char_name AS characteristic 
                          FROM cohead
                             , coitem
                             , itemsite
                             , item
                             , charass
                             ,"char"
                         WHERE (
                                   (
                                         (
                                               (
                                                     (
                                                           (cohead.cohead_id = coitem.coitem_cohead_id)
                                                         AND (coitem.coitem_itemsite_id = itemsite.itemsite_id)
                                                     )
                                                   AND (itemsite.itemsite_item_id = item.item_id)
                                               )
                                             AND (charass.charass_char_id = "char".char_id)
                                         )
                                       AND (charass.charass_target_type = 'I'::text)
                                   )
                                 AND (charass.charass_target_id = item.item_id)
                             )
                       ) data 
               LEFT JOIN charass si 
                      ON (
                             (
                                   (
                                         (data.coitem_id = si.charass_target_id)
                                       AND ('SI'::text = si.charass_target_type)
                                   )
                                 AND (si.charass_char_id = data.char_id)
                             )
                       )
                 )
         LEFT JOIN itemsite i1 
                ON (
                       (data.coitem_itemsite_id = i1.itemsite_id)
                 )
           )
   LEFT JOIN item i2 
          ON (
                 (i1.itemsite_item_id = i2.item_id)
           )
     )
LEFT JOIN charass i3 
    ON (
           (
                 (
                       (
                             (i2.item_id = i3.charass_target_id)
                           AND ('I'::text = i3.charass_target_type)
                       )
                     AND (i3.charass_char_id = data.char_id)
                 )
               AND i3.charass_default
           )
     )
)
ORDER BY (data.order_number)::character varying
, data.line_number
, data.characteristic;

Index - Schema api


View: api.saleslinecomment

Sales Order Line Item Comment

api.saleslinecomment Structure
F-Key Name Type Description
order_number character varying
line_number text
type text
date timestamp with time zone
username text
text text
SELECT (cohead.cohead_number)::character varying AS order_number
, CASE WHEN 
(coitem.coitem_subnumber = 0) THEN 
(
     (coitem.coitem_linenumber)::character varying
)::text ELSE 
(
     (
           (
                 (coitem.coitem_linenumber)::character varying
           )::text || 
           ('.'::character varying)::text
     ) || 
     (
           (coitem.coitem_subnumber)::character varying
     )::text
) END AS line_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM cohead
, coitem
, cmnttype
, comment 
WHERE (
     (
           (
                 (cohead.cohead_id = coitem.coitem_cohead_id)
               AND (comment.comment_source = 'SI'::text)
           )
         AND (comment.comment_source_id = coitem.coitem_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
)
ORDER BY cohead.cohead_number
, coitem.coitem_linenumber
, comment.comment_date DESC;

Index - Schema api


View: api.salesorder

Sales Order

api.salesorder Structure
F-Key Name Type Description
order_number character varying
site text
order_date date
pack_date date
originated_by text
sale_type text
sales_rep text
commission numeric(16,4)
tax_zone text
terms text
project_number text
customer_number text
billto_contact_number text
billto_contact_name text
billto_contact_first text
billto_contact_middle text
billto_contact_last text
billto_contact_suffix text
billto_contact_phone text
billto_contact_title text
billto_contct_fax text
billto_contact_email text
billto_name text
billto_address1 text
billto_address2 text
billto_address3 text
billto_city text
billto_state text
billto_postal_code text
billto_country text
shipto_number text
shipto_contact_number text
shipto_contact_honorific text
shipto_contact_first text
shipto_contact_middle text
shipto_contact_last text
shipto_contact_suffix text
shipto_contact_phone text
shipto_contact_title text
shipto_contact_fax text
shipto_contact_email text
shipto_name text
shipto_phone text
shipto_address1 text
shipto_address2 text
shipto_address3 text
shipto_city text
shipto_state text
shipto_postal_code text
shipto_country text
shipto_shipzone text
cust_po_number text
fob text
ship_via text
hold_type text
shipping_chgs text
shipping_form text
ship_complete boolean
currency character varying(3)
misc_charge_description text
misc_account_number text
misc_charge numeric(16,4)
freight numeric(16,4)
calculate_freight boolean
order_notes text
shipping_notes text
add_to_packing_list_batch boolean
SELECT (cohead.cohead_number)::character varying AS order_number
, whsinfo.warehous_code AS site
, cohead.cohead_orderdate AS order_date
, cohead.cohead_packdate AS pack_date
, CASE WHEN 
(cohead.cohead_origin = 'C'::bpchar) THEN 'Customer'::text WHEN 
(cohead.cohead_origin = 'I'::bpchar) THEN 'Internet'::text WHEN 
(cohead.cohead_origin = 'S'::bpchar) THEN 'Sales Rep.'::text ELSE 'Error'::text END AS originated_by
, saletype.saletype_code AS sale_type
, salesrep.salesrep_number AS sales_rep
, cohead.cohead_commission AS commission
, COALESCE
(taxzone.taxzone_code
     ,'None'::text
) AS tax_zone
, terms.terms_code AS terms
, prj.prj_number AS project_number
, custinfo.cust_number AS customer_number
, bc.cntct_number AS billto_contact_number
, cohead.cohead_billto_cntct_honorific AS billto_contact_name
, cohead.cohead_billto_cntct_first_name AS billto_contact_first
, cohead.cohead_billto_cntct_middle AS billto_contact_middle
, cohead.cohead_billto_cntct_last_name AS billto_contact_last
, cohead.cohead_billto_cntct_suffix AS billto_contact_suffix
, cohead.cohead_billto_cntct_phone AS billto_contact_phone
, cohead.cohead_billto_cntct_title AS billto_contact_title
, cohead.cohead_billto_cntct_fax AS billto_contct_fax
, cohead.cohead_billto_cntct_email AS billto_contact_email
, cohead.cohead_billtoname AS billto_name
, cohead.cohead_billtoaddress1 AS billto_address1
, cohead.cohead_billtoaddress2 AS billto_address2
, cohead.cohead_billtoaddress3 AS billto_address3
, cohead.cohead_billtocity AS billto_city
, cohead.cohead_billtostate AS billto_state
, cohead.cohead_billtozipcode AS billto_postal_code
, cohead.cohead_billtocountry AS billto_country
, shiptoinfo.shipto_num AS shipto_number
, sc.cntct_number AS shipto_contact_number
, cohead.cohead_shipto_cntct_honorific AS shipto_contact_honorific
, cohead.cohead_shipto_cntct_first_name AS shipto_contact_first
, cohead.cohead_shipto_cntct_middle AS shipto_contact_middle
, cohead.cohead_shipto_cntct_last_name AS shipto_contact_last
, cohead.cohead_shipto_cntct_suffix AS shipto_contact_suffix
, cohead.cohead_shipto_cntct_phone AS shipto_contact_phone
, cohead.cohead_shipto_cntct_title AS shipto_contact_title
, cohead.cohead_shipto_cntct_fax AS shipto_contact_fax
, cohead.cohead_shipto_cntct_email AS shipto_contact_email
, cohead.cohead_shiptoname AS shipto_name
, cohead.cohead_shiptophone AS shipto_phone
, cohead.cohead_shiptoaddress1 AS shipto_address1
, cohead.cohead_shiptoaddress2 AS shipto_address2
, cohead.cohead_shiptoaddress3 AS shipto_address3
, cohead.cohead_shiptocity AS shipto_city
, cohead.cohead_shiptostate AS shipto_state
, cohead.cohead_shiptozipcode AS shipto_postal_code
, cohead.cohead_shiptocountry AS shipto_country
, shipzone.shipzone_name AS shipto_shipzone
, cohead.cohead_custponumber AS cust_po_number
, cohead.cohead_fob AS fob
, cohead.cohead_shipvia AS ship_via
, CASE WHEN 
(cohead.cohead_holdtype = 'N'::bpchar) THEN 'None'::text WHEN 
(cohead.cohead_holdtype = 'C'::bpchar) THEN 'Credit'::text WHEN 
(cohead.cohead_holdtype = 'S'::bpchar) THEN 'Shipping'::text WHEN 
(cohead.cohead_holdtype = 'P'::bpchar) THEN 'Packing'::text WHEN 
(cohead.cohead_holdtype = 'R'::bpchar) THEN 'Return'::text ELSE 'Error'::text END AS hold_type
, shipchrg.shipchrg_name AS shipping_chgs
, shipform.shipform_name AS shipping_form
, cohead.cohead_shipcomplete AS ship_complete
, curr_symbol.curr_abbr AS currency
, cohead.cohead_misc_descrip AS misc_charge_description
, CASE WHEN 
(cohead.cohead_misc_accnt_id IS NULL) THEN NULL::text ELSE formatglaccount
(cohead.cohead_misc_accnt_id) END AS misc_account_number
, cohead.cohead_misc AS misc_charge
, cohead.cohead_freight AS freight
, cohead.cohead_calcfreight AS calculate_freight
, cohead.cohead_ordercomments AS order_notes
, cohead.cohead_shipcomments AS shipping_notes
, false AS add_to_packing_list_batch 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (cohead 
                                             LEFT JOIN cntct bc 
                                                    ON (
                                                           (cohead.cohead_billto_cntct_id = bc.cntct_id)
                                                     )
                                               )
                                       LEFT JOIN cntct sc 
                                              ON (
                                                     (cohead.cohead_shipto_cntct_id = sc.cntct_id)
                                               )
                                         )
                                 LEFT JOIN whsinfo 
                                        ON (
                                               (cohead.cohead_warehous_id = whsinfo.warehous_id)
                                         )
                                   )
                           LEFT JOIN prj 
                                  ON (
                                         (cohead.cohead_prj_id = prj.prj_id)
                                   )
                             )
                     LEFT JOIN shiptoinfo 
                            ON (
                                   (cohead.cohead_shipto_id = shiptoinfo.shipto_id)
                             )
                       )
               LEFT JOIN shipchrg 
                      ON (
                             (cohead.cohead_shipchrg_id = shipchrg.shipchrg_id)
                       )
                 )
         LEFT JOIN taxzone 
                ON (
                       (cohead.cohead_taxzone_id = taxzone.taxzone_id)
                 )
           )
   LEFT JOIN saletype 
          ON (
                 (cohead.cohead_saletype_id = saletype.saletype_id)
           )
     )
LEFT JOIN shipzone 
    ON (
           (cohead.cohead_shipzone_id = shipzone.shipzone_id)
     )
)
, custinfo
, shipform
, salesrep
, terms
, curr_symbol 
WHERE (
     (
           (
                 (
                       (cohead.cohead_cust_id = custinfo.cust_id)
                     AND (cohead.cohead_shipform_id = shipform.shipform_id)
                 )
               AND (cohead.cohead_salesrep_id = salesrep.salesrep_id)
           )
         AND (cohead.cohead_terms_id = terms.terms_id)
     )
   AND (cohead.cohead_curr_id = curr_symbol.curr_id)
);

Index - Schema api


View: api.salesordercomment

Sales Order Comment

api.salesordercomment Structure
F-Key Name Type Description
order_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (cohead.cohead_number)::character varying AS order_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM cohead
, cmnttype
, comment 
WHERE (
     (
           (comment.comment_source = 'S'::text)
         AND (comment.comment_source_id = cohead.cohead_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.salesrep

Sales Rep

api.salesrep Structure
F-Key Name Type Description
number character varying
active boolean
name text
commission_percent numeric
employee text
SELECT (salesrep.salesrep_number)::character varying AS number
, salesrep.salesrep_active AS active
, salesrep.salesrep_name AS name
, (salesrep.salesrep_commission * 
     (100)::numeric
) AS commission_percent
, emp.emp_number AS employee 
FROM (salesrep 
LEFT JOIN emp 
    ON (
           (emp.emp_id = salesrep.salesrep_emp_id)
     )
)
ORDER BY salesrep.salesrep_number;

Index - Schema api


View: api.site

Site

api.site Structure
F-Key Name Type Description
code character varying
type text
active boolean
description text
address_number text
address1 text
address2 text
address3 text
city text
state text
postal_code text
country text
address_change text
contact_number text
honorific text
first text
middle text
last text
suffix text
job_title text
phone text
fax text
email text
contact_change text
post_unassigned_transactions_to text
post_unassigned_transactions_to_description text
transit_type boolean
inventory_type boolean
next_bill_of_lading_prefix text
next_bill_of_lading_number integer
shipping_site boolean
next_count_tag_prefix text
next_count_tag_number integer
force_the_use_of_count_slips boolean
force_the_use_of_zones boolean
scheduling_sequence integer
shipping_commission numeric
tax_zone text
default_fob text
default_ship_via text
default_shipping_form text
default_cost_category text
shipping_comments text
enforce_arbl_naming_convention boolean
aisle_size integer
aisle_allow_alpha_characters boolean
rack_size integer
rack_allow_alpha_characters boolean
bin_size integer
bin_allow_alpha_characters boolean
location_size integer
location_allow_alpha_characters boolean
SELECT (whsinfo.warehous_code)::character varying AS code
, st.sitetype_name AS type
, whsinfo.warehous_active AS active
, whsinfo.warehous_descrip AS description
, m.addr_number AS address_number
, m.addr_line1 AS address1
, m.addr_line2 AS address2
, m.addr_line3 AS address3
, m.addr_city AS city
, m.addr_state AS state
, m.addr_postalcode AS postal_code
, m.addr_country AS country
,''::text AS address_change
, c.cntct_number AS contact_number
, c.cntct_honorific AS honorific
, c.cntct_first_name AS first
, c.cntct_middle AS middle
, c.cntct_last_name AS last
, c.cntct_suffix AS suffix
, c.cntct_title AS job_title
, c.cntct_phone AS phone
, c.cntct_fax AS fax
, c.cntct_email AS email
,''::text AS contact_change
, formatglaccount
(a.accnt_id) AS post_unassigned_transactions_to
, a.accnt_descrip AS post_unassigned_transactions_to_description
, whsinfo.warehous_transit AS transit_type
, CASE WHEN whsinfo.warehous_transit THEN false ELSE true END AS inventory_type
, CASE WHEN whsinfo.warehous_transit THEN ''::text ELSE whsinfo.warehous_bol_prefix END AS next_bill_of_lading_prefix
, CASE WHEN whsinfo.warehous_transit THEN 0 ELSE whsinfo.warehous_bol_number END AS next_bill_of_lading_number
, CASE WHEN whsinfo.warehous_transit THEN false ELSE whsinfo.warehous_shipping END AS shipping_site
, CASE WHEN whsinfo.warehous_transit THEN ''::text ELSE whsinfo.warehous_counttag_prefix END AS next_count_tag_prefix
, CASE WHEN whsinfo.warehous_transit THEN 0 ELSE whsinfo.warehous_counttag_number END AS next_count_tag_number
, CASE WHEN whsinfo.warehous_transit THEN false ELSE whsinfo.warehous_useslips END AS force_the_use_of_count_slips
, CASE WHEN whsinfo.warehous_transit THEN false ELSE whsinfo.warehous_usezones END AS force_the_use_of_zones
, CASE WHEN whsinfo.warehous_transit THEN 0 ELSE whsinfo.warehous_sequence END AS scheduling_sequence
, CASE WHEN whsinfo.warehous_transit THEN 
(0)::numeric ELSE 
(whsinfo.warehous_shipping_commission * 100.0) END AS shipping_commission
, CASE WHEN whsinfo.warehous_transit THEN ''::text ELSE t.taxzone_code END AS tax_zone
, CASE WHEN whsinfo.warehous_transit THEN ''::text ELSE whsinfo.warehous_fob END AS default_fob
, CASE WHEN whsinfo.warehous_transit THEN s.shipvia_code ELSE ''::text END AS default_ship_via
, CASE WHEN whsinfo.warehous_transit THEN f.shipform_name ELSE ''::text END AS default_shipping_form
, CASE WHEN whsinfo.warehous_transit THEN cc.costcat_code ELSE ''::text END AS default_cost_category
, CASE WHEN whsinfo.warehous_transit THEN whsinfo.warehous_shipcomments ELSE ''::text END AS shipping_comments
, CASE WHEN whsinfo.warehous_transit THEN false ELSE whsinfo.warehous_enforcearbl END AS enforce_arbl_naming_convention
, CASE WHEN whsinfo.warehous_transit THEN 0 WHEN whsinfo.warehous_enforcearbl THEN whsinfo.warehous_aislesize ELSE 0 END AS aisle_size
, CASE WHEN whsinfo.warehous_transit THEN false WHEN 
(whsinfo.warehous_enforcearbl 
   AND whsinfo.warehous_aislealpha
) THEN true ELSE false END AS aisle_allow_alpha_characters
, CASE WHEN whsinfo.warehous_transit THEN 0 WHEN whsinfo.warehous_enforcearbl THEN whsinfo.warehous_racksize ELSE 0 END AS rack_size
, CASE WHEN whsinfo.warehous_transit THEN false WHEN 
(whsinfo.warehous_enforcearbl 
   AND whsinfo.warehous_rackalpha
) THEN true ELSE false END AS rack_allow_alpha_characters
, CASE WHEN whsinfo.warehous_transit THEN 0 WHEN whsinfo.warehous_enforcearbl THEN whsinfo.warehous_binsize ELSE 0 END AS bin_size
, CASE WHEN whsinfo.warehous_transit THEN false WHEN 
(whsinfo.warehous_enforcearbl 
   AND whsinfo.warehous_binalpha
) THEN true ELSE false END AS bin_allow_alpha_characters
, CASE WHEN whsinfo.warehous_transit THEN 0 WHEN whsinfo.warehous_enforcearbl THEN whsinfo.warehous_locationsize ELSE 0 END AS location_size
, CASE WHEN whsinfo.warehous_transit THEN false WHEN 
(whsinfo.warehous_enforcearbl 
   AND whsinfo.warehous_locationalpha
) THEN true ELSE false END AS location_allow_alpha_characters 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (whsinfo 
                                       LEFT JOIN addr m 
                                              ON (
                                                     (whsinfo.warehous_addr_id = m.addr_id)
                                               )
                                         )
                                 LEFT JOIN cntct c 
                                        ON (
                                               (whsinfo.warehous_cntct_id = c.cntct_id)
                                         )
                                   )
                           LEFT JOIN accnt a 
                                  ON (
                                         (whsinfo.warehous_default_accnt_id = a.accnt_id)
                                   )
                             )
                     LEFT JOIN taxzone t 
                            ON (
                                   (whsinfo.warehous_taxzone_id = t.taxzone_id)
                             )
                       )
               LEFT JOIN shipvia s 
                      ON (
                             (whsinfo.warehous_shipvia_id = s.shipvia_id)
                       )
                 )
         LEFT JOIN shipform f 
                ON (
                       (whsinfo.warehous_shipform_id = f.shipform_id)
                 )
           )
   LEFT JOIN costcat cc 
          ON (
                 (whsinfo.warehous_costcat_id = cc.costcat_id)
           )
     )
LEFT JOIN sitetype st 
    ON (
           (whsinfo.warehous_sitetype_id = st.sitetype_id)
     )
)
ORDER BY whsinfo.warehous_code;

Index - Schema api


View: api.sitezone

Site Zone

api.sitezone Structure
F-Key Name Type Description
site character varying
name character varying
description text
SELECT (whsinfo.warehous_code)::character varying AS site
, (whsezone.whsezone_name)::character varying AS name
, whsezone.whsezone_descrip AS description 
FROM (whsezone 
LEFT JOIN whsinfo 
    ON (
           (whsinfo.warehous_id = whsezone.whsezone_warehous_id)
     )
);

Index - Schema api


View: api.task

Task

api.task Structure
F-Key Name Type Description
project_number text
number text
status text
name text
description text
owner text
assigned_to text
hours_budgeted numeric(18,6)
hours_actual numeric(18,6)
expenses_budgeted numeric(16,4)
expenses_actual numeric(16,4)
due date
assigned date
started date
completed date
SELECT prj.prj_number AS project_number
, prjtask.prjtask_number AS number
, CASE WHEN 
(prjtask.prjtask_status = 'P'::bpchar) THEN 'Concept'::text WHEN 
(prjtask.prjtask_status = 'O'::bpchar) THEN 'In-Process'::text WHEN 
(prjtask.prjtask_status = 'C'::bpchar) THEN 'Closed'::text ELSE 'Error'::text END AS status
, prjtask.prjtask_name AS name
, prjtask.prjtask_descrip AS description
, prjtask.prjtask_owner_username AS owner
, prjtask.prjtask_username AS assigned_to
, prjtask.prjtask_hours_budget AS hours_budgeted
, prjtask.prjtask_hours_actual AS hours_actual
, prjtask.prjtask_exp_budget AS expenses_budgeted
, prjtask.prjtask_exp_actual AS expenses_actual
, prjtask.prjtask_due_date AS due
, prjtask.prjtask_assigned_date AS assigned
, prjtask.prjtask_start_date AS started
, prjtask.prjtask_completed_date AS completed 
FROM (prjtask 
  JOIN prj 
    ON (
           (prj.prj_id = prjtask.prjtask_prj_id)
     )
);

Index - Schema api


View: api.taskcomment

Task Comment

api.taskcomment Structure
F-Key Name Type Description
project_number character varying
task_number character varying
type text
date timestamp with time zone
username text
text text
SELECT (prj.prj_number)::character varying AS project_number
, (prjtask.prjtask_number)::character varying AS task_number
, cmnttype.cmnttype_name AS type
, comment.comment_date AS date
, comment.comment_user AS username
, comment.comment_text AS text 
FROM prj
, prjtask
, cmnttype
, comment 
WHERE (
     (
           (
                 (comment.comment_source = 'TA'::text)
               AND (prj.prj_id = prjtask.prjtask_prj_id)
           )
         AND (comment.comment_source_id = prjtask.prjtask_id)
     )
   AND (comment.comment_cmnttype_id = cmnttype.cmnttype_id)
);

Index - Schema api


View: api.todo

To-Do List

api.todo Structure
F-Key Name Type Description
task_number integer
owner text
assigned_to text
task_name text
priority text
incident integer
opportunity text
account text
date_due text
date_assigned text
date_started text
date_completed text
status text
active boolean
description text
notes text
SELECT todoitem.todoitem_id AS task_number
, todoitem.todoitem_owner_username AS owner
, todoitem.todoitem_username AS assigned_to
, todoitem.todoitem_name AS task_name
, incdtpriority.incdtpriority_name AS priority
, incdt.incdt_number AS incident
, ophead.ophead_name AS opportunity
, crmacct.crmacct_number AS account
, formatdate
(todoitem.todoitem_due_date) AS date_due
, formatdate
(todoitem.todoitem_assigned_date) AS date_assigned
, formatdate
(todoitem.todoitem_start_date) AS date_started
, formatdate
(todoitem.todoitem_completed_date) AS date_completed
, CASE WHEN 
(todoitem.todoitem_status = 'P'::bpchar) THEN 'Pending Input'::text WHEN 
(todoitem.todoitem_status = 'D'::bpchar) THEN 'Deferred'::text ELSE 'Neither'::text END AS status
, todoitem.todoitem_active AS active
, todoitem.todoitem_description AS description
, todoitem.todoitem_notes AS notes 
FROM (
     (
           (
                 (todoitem 
               LEFT JOIN incdt 
                      ON (
                             (incdt.incdt_id = todoitem.todoitem_incdt_id)
                       )
                 )
         LEFT JOIN ophead 
                ON (
                       (ophead.ophead_id = todoitem.todoitem_ophead_id)
                 )
           )
   LEFT JOIN crmacct 
          ON (
                 (crmacct.crmacct_id = todoitem.todoitem_crmacct_id)
           )
     )
LEFT JOIN incdtpriority 
    ON (
           (incdtpriority.incdtpriority_id = todoitem.todoitem_priority_id)
     )
);

Index - Schema api


View: api.vendor

vendor

api.vendor Structure
F-Key Name Type Description
vendor_number character varying
vendor_type text
vendor_name text
active boolean
account_number text
address_number text
address1 text
address2 text
address3 text
city text
state text
postalcode text
country text
address_change text
default_terms text
ship_via text
default_currency character varying(3)
default_fob text
sells_purchase_order_items boolean
may_only_sell_item_source boolean
qualified boolean
matching_vo_po_amounts boolean
receives_1099 boolean
default_tax_zone text
contact1_number text
contact1_honorific text
contact1_first text
contact1_middle text
contact1_last text
contact1_suffix text
contact1_job_title text
contact1_voice text
contact1_alternate text
contact1_fax text
contact1_email text
contact1_web text
contact1_change text
contact2_number text
contact2_honorific text
contact2_first text
contact2_middle text
contact2_last text
contact2_suffix text
contact2_job_title text
contact2_voice text
contact2_alternate text
contact2_fax text
contact2_email text
contact2_web text
contact2_change text
notes text
po_comments text
allow_email_po_delivery boolean
po_edi_email text
po_edi_cc text
po_edi_subject text
po_edi_filename text
po_edi_emailbody text
SELECT (vendinfo.vend_number)::character varying AS vendor_number
, vendtype.vendtype_code AS vendor_type
, vendinfo.vend_name AS vendor_name
, vendinfo.vend_active AS active
, vendinfo.vend_accntnum AS account_number
, addr.addr_number AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postalcode
, addr.addr_country AS country
,''::text AS address_change
, terms.terms_code AS default_terms
, vendinfo.vend_shipvia AS ship_via
, curr_symbol.curr_abbr AS default_currency
, CASE WHEN 
(vendinfo.vend_fobsource = 'W'::bpchar) THEN 'Receiving Site'::text ELSE vendinfo.vend_fob END AS default_fob
, vendinfo.vend_po AS sells_purchase_order_items
, vendinfo.vend_restrictpurch AS may_only_sell_item_source
, vendinfo.vend_qualified AS qualified
, vendinfo.vend_match AS matching_vo_po_amounts
, vendinfo.vend_1099 AS receives_1099
, taxzone.taxzone_code AS default_tax_zone
, c1.cntct_number AS contact1_number
, c1.cntct_honorific AS contact1_honorific
, c1.cntct_first_name AS contact1_first
, c1.cntct_middle AS contact1_middle
, c1.cntct_last_name AS contact1_last
, c1.cntct_suffix AS contact1_suffix
, c1.cntct_title AS contact1_job_title
, c1.cntct_phone AS contact1_voice
, c1.cntct_phone2 AS contact1_alternate
, c1.cntct_fax AS contact1_fax
, c1.cntct_email AS contact1_email
, c1.cntct_webaddr AS contact1_web
,''::text AS contact1_change
, c2.cntct_number AS contact2_number
, c2.cntct_honorific AS contact2_honorific
, c2.cntct_first_name AS contact2_first
, c2.cntct_middle AS contact2_middle
, c2.cntct_last_name AS contact2_last
, c2.cntct_suffix AS contact2_suffix
, c2.cntct_title AS contact2_job_title
, c2.cntct_phone AS contact2_voice
, c2.cntct_phone2 AS contact2_alternate
, c2.cntct_fax AS contact2_fax
, c2.cntct_email AS contact2_email
, c2.cntct_webaddr AS contact2_web
,''::text AS contact2_change
, vendinfo.vend_comments AS notes
, vendinfo.vend_pocomments AS po_comments
, vendinfo.vend_emailpodelivery AS allow_email_po_delivery
, vendinfo.vend_ediemail AS po_edi_email
, vendinfo.vend_edicc AS po_edi_cc
, vendinfo.vend_edisubject AS po_edi_subject
, vendinfo.vend_edifilename AS po_edi_filename
, vendinfo.vend_ediemailbody AS po_edi_emailbody 
FROM (
     (
           (
                 (
                       (
                             (
                                   (vendinfo 
                                 LEFT JOIN addr 
                                        ON (
                                               (vendinfo.vend_addr_id = addr.addr_id)
                                         )
                                   )
                           LEFT JOIN cntct c1 
                                  ON (
                                         (vendinfo.vend_cntct1_id = c1.cntct_id)
                                   )
                             )
                     LEFT JOIN cntct c2 
                            ON (
                                   (vendinfo.vend_cntct2_id = c2.cntct_id)
                             )
                       )
               LEFT JOIN taxzone 
                      ON (
                             (vendinfo.vend_taxzone_id = taxzone.taxzone_id)
                       )
                 )
         LEFT JOIN curr_symbol 
                ON (
                       (vendinfo.vend_curr_id = curr_symbol.curr_id)
                 )
           )
   LEFT JOIN terms 
          ON (
                 (vendinfo.vend_terms_id = terms.terms_id)
           )
     )
LEFT JOIN vendtype 
    ON (
           (vendinfo.vend_vendtype_id = vendtype.vendtype_id)
     )
)
ORDER BY vendinfo.vend_number;

Index - Schema api


View: api.vendoraddress

vendor address

api.vendoraddress Structure
F-Key Name Type Description
vendor_number character varying
vendor_name text
vendor_address_number character varying
vendor_address_name text
address_number text
address1 text
address2 text
address3 text
city text
state text
postalcode text
country text
address_change text
contact_number text
contact_honorific text
contact_first text
contact_middle text
contact_last text
contact_suffix text
contact_job_title text
contact_voice text
contact_alternate text
contact_fax text
contact_email text
contact_web text
contact_change text
notes text
SELECT (vendinfo.vend_number)::character varying AS vendor_number
, vendinfo.vend_name AS vendor_name
, (vendaddrinfo.vendaddr_code)::character varying AS vendor_address_number
, vendaddrinfo.vendaddr_name AS vendor_address_name
, addr.addr_number AS address_number
, addr.addr_line1 AS address1
, addr.addr_line2 AS address2
, addr.addr_line3 AS address3
, addr.addr_city AS city
, addr.addr_state AS state
, addr.addr_postalcode AS postalcode
, addr.addr_country AS country
,''::text AS address_change
, cntct.cntct_number AS contact_number
, cntct.cntct_honorific AS contact_honorific
, cntct.cntct_first_name AS contact_first
, cntct.cntct_middle AS contact_middle
, cntct.cntct_last_name AS contact_last
, cntct.cntct_suffix AS contact_suffix
, cntct.cntct_title AS contact_job_title
, cntct.cntct_phone AS contact_voice
, cntct.cntct_phone2 AS contact_alternate
, cntct.cntct_fax AS contact_fax
, cntct.cntct_email AS contact_email
, cntct.cntct_webaddr AS contact_web
,''::text AS contact_change
, vendaddrinfo.vendaddr_comments AS notes 
FROM (
     (
           (vendaddrinfo 
         LEFT JOIN vendinfo 
                ON (
                       (vendinfo.vend_id = vendaddrinfo.vendaddr_vend_id)
                 )
           )
   LEFT JOIN addr 
          ON (
                 (vendaddrinfo.vendaddr_addr_id = addr.addr_id)
           )
     )
LEFT JOIN cntct 
    ON (
           (vendaddrinfo.vendaddr_cntct_id = cntct.cntct_id)
     )
)
ORDER BY vendaddrinfo.vendaddr_code;

Index - Schema api


View: api.vendortype

Vendor Type

api.vendortype Structure
F-Key Name Type Description
code character varying
description text
SELECT (vendtype.vendtype_code)::character varying AS code
, vendtype.vendtype_descrip AS description 
FROM vendtype 
ORDER BY vendtype.vendtype_code;

Index - Schema api


Function: api.insertsalesline(api.salesline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNEW ALIAS FOR $1;
  _r RECORD;

BEGIN

  IF (NOT EXISTS (SELECT cohead_id FROM cohead WHERE cohead_number=pNEW.order_number)) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed because Sales Order % not found', pNEW.order_number;
  END IF;

  IF (NOT EXISTS (SELECT item_id FROM item WHERE item_number=pNEW.item_number)) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed because Item Number % not found', pNEW.item_number;
  END IF;

  SELECT * INTO _r
  FROM cohead, itemsite, item, whsinfo
  WHERE ((cohead_number=pNEW.order_number)
  AND (itemsite_warehous_id=warehous_id
  AND (itemsite_item_id=item_id)
  AND (itemsite_active)
  AND (item_number=pNEW.item_number)
  AND (warehous_active)
  AND (warehous_id=COALESCE(getWarehousId(pNEW.sold_from_site,'ALL'),cohead_warehous_id,fetchprefwarehousid()))));

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed with unknown failure to retrieve Sales Order';
  END IF;

  INSERT INTO coitem (
    coitem_cohead_id,
    coitem_linenumber,
    coitem_itemsite_id,
    coitem_status,
    coitem_scheddate,
    coitem_promdate,
    coitem_qtyord,
    coitem_qty_uom_id,
    coitem_qty_invuomratio,
    coitem_qtyshipped,
    coitem_unitcost,
    coitem_price,
    coitem_price_uom_id,
    coitem_price_invuomratio,
    coitem_custprice,
    coitem_order_id,
    coitem_memo,
    coitem_imported,
    coitem_qtyreturned,
    coitem_custpn,
    coitem_order_type,
    coitem_substitute_item_id,
    coitem_prcost,
    coitem_taxtype_id,
    coitem_warranty,
    coitem_cos_accnt_id,
    coitem_rev_accnt_id)
  VALUES (
    _r.cohead_id,
    pNEW.line_number::INTEGER,
    _r.itemsite_id,
    pNEW.status,
    pNEW.scheduled_date,
    pNEW.promise_date,
    pNEW.qty_ordered,
    COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),
    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),_r.item_inv_uom_id),
    0,
    stdCost(_r.item_id),
    COALESCE(pNEW.net_unit_price,itemPrice(_r.item_id,_r.cohead_cust_id,
             _r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate)),
    COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),
    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),_r.item_price_uom_id),
    itemPrice(_r.item_id,_r.cohead_cust_id,_r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate),
    -1,
    pNEW.notes,
    true,
    0,
    pNEW.customer_pn,
    CASE
      WHEN ((pNEW.create_order  AND (_r.item_type = 'M')) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createwo)) THEN
        'W'
      WHEN ((pNEW.create_order AND (_r.item_type = 'P')) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopr)) THEN
        'R'
      WHEN ((pNEW.create_order AND (_r.item_type = 'P') AND (_r.itemsite_createsopo)) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopo)) THEN
        'P'
    END,
    getitemid(pNEW.substitute_for),
    pNEW.overwrite_po_price,
    COALESCE(getTaxTypeId(pNEW.tax_type), getItemTaxType(_r.itemsite_item_id, _r.cohead_taxzone_id)),
    pNEW.warranty,
    getGlAccntId(pNEW.alternate_cos_account),
    getGlAccntId(pNEW.alternate_rev_account)
    );

  RETURN TRUE;
END;

Schema fixcountry

Schema to hold contents of fixcountry


Table: fixcountry.pkgcmd

fixcountry.pkgcmd Structure
F-Key Name Type Description
cmd_id integer PRIMARY KEY DEFAULT nextval('public.cmd_cmd_id_seq'::regclass)
cmd_module text NOT NULL
cmd_title text NOT NULL
cmd_descrip text
cmd_privname text
cmd_executable text NOT NULL
cmd_name text

Table fixcountry.pkgcmd Inherits cmd,

Tables referencing this one via Foreign Key Constraints:

Index - Schema fixcountry


Table: fixcountry.pkgcmdarg

fixcountry.pkgcmdarg Structure
F-Key Name Type Description
cmdarg_id integer PRIMARY KEY DEFAULT nextval('public.cmdarg_cmdarg_id_seq'::regclass)
fixcountry.pkgcmd.cmd_id cmdarg_cmd_id integer NOT NULL
cmdarg_order integer NOT NULL
cmdarg_arg text NOT NULL

Table fixcountry.pkgcmdarg Inherits cmdarg,

Index - Schema fixcountry


Table: fixcountry.pkgimage

fixcountry.pkgimage Structure
F-Key Name Type Description
image_id integer PRIMARY KEY DEFAULT nextval('public.image_image_id_seq'::regclass)
image_name text
image_descrip text
image_data text

Table fixcountry.pkgimage Inherits image,

Index - Schema fixcountry


Table: fixcountry.pkgmetasql

fixcountry.pkgmetasql Structure
F-Key Name Type Description
metasql_id integer PRIMARY KEY DEFAULT nextval('public.metasql_metasql_id_seq'::regclass)
metasql_group text
metasql_name text
metasql_notes text
metasql_query text
metasql_lastuser text
metasql_lastupdate date
metasql_grade integer NOT NULL

Table fixcountry.pkgmetasql Inherits metasql,

Index - Schema fixcountry


Table: fixcountry.pkgpriv

fixcountry.pkgpriv Structure
F-Key Name Type Description
priv_id integer PRIMARY KEY DEFAULT nextval('public.priv_priv_id_seq'::regclass)
priv_module text
priv_name text
priv_descrip text
priv_seq integer

Table fixcountry.pkgpriv Inherits priv,

Index - Schema fixcountry


Table: fixcountry.pkgreport

fixcountry.pkgreport Structure
F-Key Name Type Description
report_id integer PRIMARY KEY DEFAULT nextval('public.report_report_id_seq'::regclass)
report_name text
report_sys boolean
report_source text
report_descrip text
report_grade integer NOT NULL
report_loaddate timestamp without time zone

Table fixcountry.pkgreport Inherits report,

Index - Schema fixcountry


Table: fixcountry.pkgscript

fixcountry.pkgscript Structure
F-Key Name Type Description
script_id integer PRIMARY KEY DEFAULT nextval('public.script_script_id_seq'::regclass)
script_name text NOT NULL
script_order integer NOT NULL
script_enabled boolean NOT NULL DEFAULT false
script_source text NOT NULL
script_notes text

Table fixcountry.pkgscript Inherits script,

Index - Schema fixcountry


Table: fixcountry.pkguiform

fixcountry.pkguiform Structure
F-Key Name Type Description
uiform_id integer PRIMARY KEY DEFAULT nextval('public.uiform_uiform_id_seq'::regclass)
uiform_name text NOT NULL
uiform_order integer NOT NULL
uiform_enabled boolean NOT NULL DEFAULT false
uiform_source text NOT NULL
uiform_notes text

Table fixcountry.pkguiform Inherits uiform,

Index - Schema fixcountry


Schema public

standard public schema


Table: public.acalitem

Absolute Calendar Item information

public.acalitem Structure
F-Key Name Type Description
acalitem_id integer PRIMARY KEY DEFAULT nextval(('"xcalitem_xcalitem_id_seq"'::text)::regclass)
acalitem_calhead_id integer
acalitem_periodstart date
acalitem_periodlength integer
acalitem_name text

Index - Schema public


Table: public.accnt

General Ledger (G/L) Account Number information

public.accnt Structure
F-Key Name Type Description
accnt_id integer PRIMARY KEY DEFAULT nextval(('accnt_accnt_id_seq'::text)::regclass)
accnt_number text
accnt_descrip text
accnt_comments text
accnt_profit text
accnt_sub text
accnt_type character(1) NOT NULL
accnt_extref text
public.company.company_number accnt_company text
accnt_forwardupdate boolean
accnt_subaccnttype_code text
public.curr_symbol.curr_id accnt_curr_id integer DEFAULT basecurrid()
accnt_active boolean NOT NULL DEFAULT true
accnt_name text

 

public.accnt Constraints
Name Constraint
accnt_accnt_type_check CHECK ((accnt_type = ANY (ARRAY['A'::bpchar, 'E'::bpchar, 'L'::bpchar, 'Q'::bpchar, 'R'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.addr

Postal Address

public.addr Structure
F-Key Name Type Description
addr_id serial PRIMARY KEY
addr_active boolean DEFAULT true
addr_line1 text DEFAULT ''::text
addr_line2 text DEFAULT ''::text
addr_line3 text DEFAULT ''::text
addr_city text DEFAULT ''::text
addr_state text DEFAULT ''::text
addr_postalcode text DEFAULT ''::text
addr_country text DEFAULT ''::text
addr_notes text DEFAULT ''::text
addr_number text UNIQUE NOT NULL

 

public.addr Constraints
Name Constraint
addr_addr_number_check CHECK ((addr_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


View: public.address

public.address Structure
F-Key Name Type Description
addr_id integer
addr_active boolean
addr_line1 text
addr_line2 text
addr_line3 text
addr_city text
addr_state text
addr_postalcode text
addr_country text
addr_notes text
addr_number text
crmacct_id integer
crmacct_number text
crmacct_name text
SELECT addresses.addr_id
, addresses.addr_active
, addresses.addr_line1
, addresses.addr_line2
, addresses.addr_line3
, addresses.addr_city
, addresses.addr_state
, addresses.addr_postalcode
, addresses.addr_country
, addresses.addr_notes
, addresses.addr_number
, addresses.crmacct_id
, addresses.crmacct_number
, addresses.crmacct_name 
FROM (
     (
           (
                 (
                  SELECT base.addr_id
                       , base.addr_active
                       , base.addr_line1
                       , base.addr_line2
                       , base.addr_line3
                       , base.addr_city
                       , base.addr_state
                       , base.addr_postalcode
                       , base.addr_country
                       , base.addr_notes
                       , base.addr_number
                       , base.crmacct_id
                       , base.crmacct_number
                       , base.crmacct_name 
                    FROM (
                             (
                                   (
                                         (
                                          SELECT addr.addr_id
                                               , addr.addr_active
                                               , addr.addr_line1
                                               , addr.addr_line2
                                               , addr.addr_line3
                                               , addr.addr_city
                                               , addr.addr_state
                                               , addr.addr_postalcode
                                               , addr.addr_country
                                               , addr.addr_notes
                                               , addr.addr_number
                                               , COALESCE
                                               (crmacct.crmacct_id
                                                     , (-1)
                                               ) AS crmacct_id
                                               , crmacct.crmacct_number
                                               , crmacct.crmacct_name 
                                            FROM (
                                                     (addr 
                                                   LEFT JOIN cntct 
                                                          ON (
                                                                 (cntct.cntct_addr_id = addr.addr_id)
                                                           )
                                                     )
                                             LEFT JOIN crmacct 
                                                    ON (
                                                           (crmacct.crmacct_id = cntct.cntct_crmacct_id)
                                                     )
                                               )
                                          EXCEPTSELECT addr.addr_id
                                               , addr.addr_active
                                               , addr.addr_line1
                                               , addr.addr_line2
                                               , addr.addr_line3
                                               , addr.addr_city
                                               , addr.addr_state
                                               , addr.addr_postalcode
                                               , addr.addr_country
                                               , addr.addr_notes
                                               , addr.addr_number
                                               , (-1)
                                               , NULL::unknown
                                               , NULL::unknown 
                                            FROM (
                                                     (addr 
                                                        JOIN vendinfo 
                                                          ON (
                                                                 (vendinfo.vend_addr_id = addr.addr_id)
                                                           )
                                                     )
                                                  JOIN crmacct 
                                                    ON (
                                                           (vendinfo.vend_id = crmacct.crmacct_vend_id)
                                                     )
                                               )
                                         )
                                    EXCEPTSELECT addr.addr_id
                                         , addr.addr_active
                                         , addr.addr_line1
                                         , addr.addr_line2
                                         , addr.addr_line3
                                         , addr.addr_city
                                         , addr.addr_state
                                         , addr.addr_postalcode
                                         , addr.addr_country
                                         , addr.addr_notes
                                         , addr.addr_number
                                         , (-1)
                                         , NULL::unknown
                                         , NULL::unknown 
                                      FROM (
                                               (addr 
                                                  JOIN vendaddrinfo 
                                                    ON (
                                                           (vendaddrinfo.vendaddr_addr_id = addr.addr_id)
                                                     )
                                               )
                                            JOIN crmacct 
                                              ON (
                                                     (vendaddrinfo.vendaddr_vend_id = crmacct.crmacct_vend_id)
                                               )
                                         )
                                   )
                              EXCEPTSELECT addr.addr_id
                                   , addr.addr_active
                                   , addr.addr_line1
                                   , addr.addr_line2
                                   , addr.addr_line3
                                   , addr.addr_city
                                   , addr.addr_state
                                   , addr.addr_postalcode
                                   , addr.addr_country
                                   , addr.addr_notes
                                   , addr.addr_number
                                   , (-1)
                                   , NULL::unknown
                                   , NULL::unknown 
                                FROM (
                                         (addr 
                                            JOIN taxauth 
                                              ON (
                                                     (taxauth.taxauth_addr_id = addr.addr_id)
                                               )
                                         )
                                      JOIN crmacct 
                                        ON (
                                               (taxauth.taxauth_id = crmacct.crmacct_taxauth_id)
                                         )
                                   )
                             )
                        EXCEPTSELECT addr.addr_id
                             , addr.addr_active
                             , addr.addr_line1
                             , addr.addr_line2
                             , addr.addr_line3
                             , addr.addr_city
                             , addr.addr_state
                             , addr.addr_postalcode
                             , addr.addr_country
                             , addr.addr_notes
                             , addr.addr_number
                             , (-1)
                             , NULL::unknown
                             , NULL::unknown 
                          FROM (
                                   (addr 
                                      JOIN shiptoinfo 
                                        ON (
                                               (shiptoinfo.shipto_addr_id = addr.addr_id)
                                         )
                                   )
                                JOIN crmacct 
                                  ON (
                                         (shiptoinfo.shipto_cust_id = crmacct.crmacct_cust_id)
                                   )
                             )
                       ) base 
                   UNIONSELECT addr.addr_id
                       , addr.addr_active
                       , addr.addr_line1
                       , addr.addr_line2
                       , addr.addr_line3
                       , addr.addr_city
                       , addr.addr_state
                       , addr.addr_postalcode
                       , addr.addr_country
                       , addr.addr_notes
                       , addr.addr_number
                       , crmacct.crmacct_id
                       , crmacct.crmacct_number
                       , crmacct.crmacct_name 
                    FROM (
                             (addr 
                                JOIN vendinfo 
                                  ON (
                                         (vendinfo.vend_addr_id = addr.addr_id)
                                   )
                             )
                          JOIN crmacct 
                            ON (
                                   (vendinfo.vend_id = crmacct.crmacct_vend_id)
                             )
                       )
                 )
             UNIONSELECT addr.addr_id
                 , addr.addr_active
                 , addr.addr_line1
                 , addr.addr_line2
                 , addr.addr_line3
                 , addr.addr_city
                 , addr.addr_state
                 , addr.addr_postalcode
                 , addr.addr_country
                 , addr.addr_notes
                 , addr.addr_number
                 , crmacct.crmacct_id
                 , crmacct.crmacct_number
                 , crmacct.crmacct_name 
              FROM (
                       (addr 
                          JOIN vendaddrinfo 
                            ON (
                                   (vendaddrinfo.vendaddr_addr_id = addr.addr_id)
                             )
                       )
                    JOIN crmacct 
                      ON (
                             (vendaddrinfo.vendaddr_vend_id = crmacct.crmacct_vend_id)
                       )
                 )
           )
       UNIONSELECT addr.addr_id
           , addr.addr_active
           , addr.addr_line1
           , addr.addr_line2
           , addr.addr_line3
           , addr.addr_city
           , addr.addr_state
           , addr.addr_postalcode
           , addr.addr_country
           , addr.addr_notes
           , addr.addr_number
           , crmacct.crmacct_id
           , crmacct.crmacct_number
           , crmacct.crmacct_name 
        FROM (
                 (addr 
                    JOIN taxauth 
                      ON (
                             (taxauth.taxauth_addr_id = addr.addr_id)
                       )
                 )
              JOIN crmacct 
                ON (
                       (taxauth.taxauth_id = crmacct.crmacct_taxauth_id)
                 )
           )
     )
 UNIONSELECT addr.addr_id
     , addr.addr_active
     , addr.addr_line1
     , addr.addr_line2
     , addr.addr_line3
     , addr.addr_city
     , addr.addr_state
     , addr.addr_postalcode
     , addr.addr_country
     , addr.addr_notes
     , addr.addr_number
     , crmacct.crmacct_id
     , crmacct.crmacct_number
     , crmacct.crmacct_name 
  FROM (
           (addr 
              JOIN shiptoinfo 
                ON (
                       (shiptoinfo.shipto_addr_id = addr.addr_id)
                 )
           )
        JOIN crmacct 
          ON (
                 (shiptoinfo.shipto_cust_id = crmacct.crmacct_cust_id)
           )
     )
) addresses 
ORDER BY addresses.addr_country
, addresses.addr_state
, addresses.addr_postalcode
, addresses.addr_line1
, addresses.addr_line2
, addresses.addr_line3;

Index - Schema public


Table: public.alarm

This table is the open alarms.

public.alarm Structure
F-Key Name Type Description
alarm_id serial PRIMARY KEY
alarm_number text NOT NULL
alarm_event boolean NOT NULL DEFAULT false
alarm_email boolean NOT NULL DEFAULT false
alarm_sysmsg boolean NOT NULL DEFAULT false
alarm_trigger timestamp with time zone
alarm_time timestamp with time zone
alarm_time_offset integer
alarm_time_qualifier text
alarm_creator text
alarm_event_recipient text
alarm_email_recipient text
alarm_sysmsg_recipient text
alarm_source text
alarm_source_id integer

Index - Schema public


Table: public.apaccnt

Accounts Payable (A/P) Account assignment information

public.apaccnt Structure
F-Key Name Type Description
apaccnt_id serial PRIMARY KEY
apaccnt_vendtype_id integer
apaccnt_vendtype text
apaccnt_ap_accnt_id integer NOT NULL
apaccnt_prepaid_accnt_id integer
apaccnt_discount_accnt_id integer

Index - Schema public


Table: public.apapply

Applications (e.g., Payments, A/P Credit Memos) made to Accounts Payable (A/P) Documents

public.apapply Structure
F-Key Name Type Description
apapply_id serial PRIMARY KEY
public.vendinfo.vend_id apapply_vend_id integer
apapply_postdate date
apapply_username text
apapply_source_apopen_id integer

If apapply_source_doctype is "C" (credit memo) then apapply_source_apopen_id acts as a foreign key to the apopen table. If the source doctype is "K" (check) then the apapply_source_apopen_id acts as a foreign key to the checkhead table. If the apapply_source_apopen_id is -1 then the internal id of the source document is not known (always the case for checks posted before release 3.2.0BETA).
apapply_source_doctype text
apapply_source_docnumber text
apapply_target_apopen_id integer
apapply_target_doctype text
apapply_target_docnumber text
apapply_journalnumber integer
apapply_amount numeric(20,2)
public.curr_symbol.curr_id apapply_curr_id integer DEFAULT basecurrid()
apapply_target_paid numeric(20,2)
public.checkhead.checkhead_id apapply_checkhead_id integer

Index - Schema public


Table: public.apcreditapply

Temporary table for storing details of Accounts Payable (A/P) Credit Memo applications before those applications are posted

public.apcreditapply Structure
F-Key Name Type Description
apcreditapply_id serial PRIMARY KEY
apcreditapply_source_apopen_id integer
apcreditapply_target_apopen_id integer
apcreditapply_amount numeric(20,2)
public.curr_symbol.curr_id apcreditapply_curr_id integer DEFAULT basecurrid()

Index - Schema public


View: public.apmemo

public.apmemo Structure
F-Key Name Type Description
apopen_id integer
apopen_docnumber text
SELECT apopen.apopen_id
, apopen.apopen_docnumber 
FROM apopen 
WHERE (apopen.apopen_doctype = ANY 
     (ARRAY['D'::bpchar
           ,'C'::bpchar]
     )
);

Index - Schema public


Table: public.apopen

Accounts Payable (A/P) open Items information

public.apopen Structure
F-Key Name Type Description
apopen_id integer PRIMARY KEY DEFAULT nextval(('"apopen_apopen_id_seq"'::text)::regclass)
apopen_docdate date
apopen_duedate date
apopen_terms_id integer
public.vendinfo.vend_id apopen_vend_id integer
apopen_doctype character(1)
apopen_docnumber text
apopen_amount numeric(20,2)
apopen_notes text
apopen_posted boolean
apopen_reference text
apopen_invcnumber text
apopen_ponumber text
apopen_journalnumber integer
apopen_paid numeric(20,2)
apopen_open boolean
apopen_username text
apopen_discount boolean NOT NULL DEFAULT false
apopen_accnt_id integer DEFAULT (-1)
public.curr_symbol.curr_id apopen_curr_id integer DEFAULT basecurrid()
apopen_closedate date
apopen_distdate date
apopen_void boolean NOT NULL DEFAULT false
apopen_curr_rate numeric NOT NULL
apopen_discountable_amount numeric(20,2)
apopen_status text

 

public.apopen Constraints
Name Constraint
apopen_apopen_status_check CHECK ((((apopen_status = 'O'::text) OR (apopen_status = 'H'::text)) OR (apopen_status = 'C'::text)))
apopen_apopen_status_notnull CHECK ((apopen_status IS NOT NULL))

Tables referencing this one via Foreign Key Constraints:

apopen_apopen_open_idx apopen_open apopen_apopen_vend_id_idx apopen_vend_id

Index - Schema public


Table: public.apopentax

public.apopentax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.apopen.apopen_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.apopentax Inherits taxhist,

Index - Schema public


Table: public.apselect

Temporary table for storing details of Accounts Payable (A/P) Payment selections

public.apselect Structure
F-Key Name Type Description
apselect_id serial PRIMARY KEY
apselect_apopen_id integer UNIQUE NOT NULL
apselect_amount numeric(20,2) NOT NULL
apselect_bankaccnt_id integer
public.curr_symbol.curr_id apselect_curr_id integer DEFAULT basecurrid()
apselect_date date
apselect_discount numeric(20,2) NOT NULL DEFAULT 0.0
apselect_apselect_apopen_id_idx apselect_apopen_id

Index - Schema public


Table: public.araccnt

Accounts Receivable (A/R) Account assignment information

public.araccnt Structure
F-Key Name Type Description
araccnt_id integer PRIMARY KEY DEFAULT nextval(('araccnt_araccnt_id_seq'::text)::regclass)
araccnt_custtype_id integer
araccnt_custtype text
araccnt_freight_accnt_id integer
araccnt_ar_accnt_id integer
araccnt_prepaid_accnt_id integer
araccnt_deferred_accnt_id integer
araccnt_discount_accnt_id integer

Index - Schema public


Table: public.arapply

Applications (e.g., Cash Receipts, A/R Credit Memos) made to Accounts Receivable (A/R) Documents

public.arapply Structure
F-Key Name Type Description
arapply_id serial PRIMARY KEY
arapply_postdate date
arapply_cust_id integer
arapply_source_doctype text
arapply_source_docnumber text
arapply_target_doctype text
arapply_target_docnumber text
arapply_fundstype text
arapply_refnumber text
arapply_applied numeric(20,2)
arapply_closed boolean
arapply_journalnumber text
arapply_source_aropen_id integer
arapply_target_aropen_id integer
arapply_username text
public.curr_symbol.curr_id arapply_curr_id integer DEFAULT basecurrid()
arapply_distdate date NOT NULL
arapply_target_paid numeric(20,2)
arapply_reftype text
arapply_ref_id integer
arapply_arapply_target_docnumber_idx arapply_target_docnumber

Index - Schema public


Table: public.arcreditapply

Temporary table for storing details of Accounts Receivable (A/R) Credit Memo applications before those applications are posted

public.arcreditapply Structure
F-Key Name Type Description
arcreditapply_id serial PRIMARY KEY
arcreditapply_source_aropen_id integer
arcreditapply_target_aropen_id integer
arcreditapply_amount numeric(20,2)
public.curr_symbol.curr_id arcreditapply_curr_id integer DEFAULT basecurrid()
arcreditapply_reftype text
arcreditapply_ref_id integer

Index - Schema public


View: public.armemo

public.armemo Structure
F-Key Name Type Description
aropen_id integer
aropen_docnumber text
SELECT aropen.aropen_id
, aropen.aropen_docnumber 
FROM aropen 
WHERE (aropen.aropen_doctype = ANY 
     (ARRAY['D'::bpchar
           ,'C'::bpchar
           ,'R'::bpchar]
     )
)
UNIONSELECT cmhead.cmhead_id AS aropen_id
, cmhead.cmhead_number AS aropen_docnumber 
FROM cmhead;

Index - Schema public


Table: public.aropen

Accounts Receivable (A/R) open Items information

public.aropen Structure
F-Key Name Type Description
aropen_id integer PRIMARY KEY DEFAULT nextval(('"aropen_aropen_id_seq"'::text)::regclass)
aropen_docdate date NOT NULL
aropen_duedate date NOT NULL
aropen_terms_id integer
public.custinfo.cust_id aropen_cust_id integer
aropen_doctype character(1)
aropen_docnumber text
aropen_applyto text
aropen_ponumber text
aropen_amount numeric(20,2) NOT NULL
aropen_notes text
aropen_posted boolean NOT NULL DEFAULT false
public.salesrep.salesrep_id aropen_salesrep_id integer
aropen_commission_due numeric(20,2)
aropen_commission_paid boolean DEFAULT false
aropen_ordernumber text
aropen_cobmisc_id integer DEFAULT (-1)
aropen_journalnumber integer
aropen_paid numeric(20,2)
aropen_open boolean
aropen_username text
aropen_rsncode_id integer
aropen_salescat_id integer DEFAULT (-1)
aropen_accnt_id integer DEFAULT (-1)
public.curr_symbol.curr_id aropen_curr_id integer DEFAULT basecurrid()
aropen_closedate date
aropen_distdate date
aropen_curr_rate numeric NOT NULL
aropen_discount boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

aropen_aropen_cust_id_idx aropen_cust_id aropen_aropen_docnumber_idx aropen_docnumber aropen_aropen_doctype_idx aropen_doctype aropen_aropen_open_idx aropen_open aropen_posted_idx aropen_posted

Index - Schema public


Table: public.aropenalloc

public.aropenalloc Structure
F-Key Name Type Description
aropenalloc_aropen_id integer PRIMARY KEY
aropenalloc_doctype character(1) PRIMARY KEY
aropenalloc_doc_id integer PRIMARY KEY
aropenalloc_amount numeric(20,2) NOT NULL DEFAULT 0.00
aropenalloc_curr_id integer DEFAULT basecurrid()
aropenalloc_aropen_id_idx aropenalloc_aropen_id aropenalloc_doc_id_idx aropenalloc_doc_id

Index - Schema public


Table: public.aropentax

public.aropentax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.aropen.aropen_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.aropentax Inherits taxhist,

Index - Schema public


Table: public.asohist

Archived Sales history

public.asohist Structure
F-Key Name Type Description
asohist_id serial PRIMARY KEY
asohist_cust_id integer
asohist_itemsite_id integer
asohist_shipdate date
asohist_invcdate date
asohist_duedate date
asohist_promisedate date
asohist_ordernumber text
asohist_invcnumber text
asohist_qtyshipped numeric(18,6)
asohist_unitprice numeric(16,4)
asohist_unitcost numeric(16,6)
asohist_billtoname text
asohist_billtoaddress1 text
asohist_billtoaddress2 text
asohist_billtoaddress3 text
asohist_billtocity text
asohist_billtostate text
asohist_billtozip text
asohist_shiptoname text
asohist_shiptoaddress1 text
asohist_shiptoaddress2 text
asohist_shiptoaddress3 text
asohist_shiptocity text
asohist_shiptostate text
asohist_shiptozip text
asohist_shipto_id integer
asohist_shipvia text
asohist_salesrep_id integer
asohist_misc_type character(1)
asohist_misc_descrip text
asohist_misc_id integer
asohist_commission numeric(16,4)
asohist_commissionpaid boolean
asohist_doctype text
asohist_orderdate date
asohist_imported boolean
asohist_ponumber text
public.curr_symbol.curr_id asohist_curr_id integer DEFAULT basecurrid()
public.taxtype.taxtype_id asohist_taxtype_id integer
public.taxzone.taxzone_id asohist_taxzone_id integer

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.asohisttax

public.asohisttax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.asohist.asohist_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.asohisttax Inherits taxhist,

Index - Schema public


Table: public.atlasmap

Describes heuristics for finding a CSVImp atlas for a given CSV file. When looking for a CSV Atlas to use when importing a CSV file, the first atlasmap record found that matches the CSV file is used to select the Atlas file and Map in that Atlas to import the CSV file.

public.atlasmap Structure
F-Key Name Type Description
atlasmap_id serial PRIMARY KEY

The internal id of this CSVImp atlas mapping.
atlasmap_name text UNIQUE NOT NULL

The human-readable name of this atlas mapping.
atlasmap_filter text NOT NULL

A regular expression that should match the CSV file. Which part of the file that matches is determined by the filter type.
atlasmap_filtertype text NOT NULL

A description of what aspect of the CSV file the filter should be compared with. Handled values are: 'filename' - the filter is matched against the name of the file; and 'firstline' - the filter is matched against the first line of the file contents.
atlasmap_atlas text NOT NULL

The name of the CSVImp Atlas file. This should be a simple pathname, not an absolute or relative name if possible. The full path will be determined by concatenating the operating-system-specific CSV Atlas default directory with the value here unless this is an absolute pathname.
atlasmap_map text NOT NULL

The name of the Map inside the Atlas to use if the filter and filter type match the CVS file.
atlasmap_headerline boolean NOT NULL DEFAULT false

An indicator of whether the first line of the CSV file should be treated as a header line or as data.

 

public.atlasmap Constraints
Name Constraint
atlasmap_atlasmap_name_check CHECK ((atlasmap_name <> ''::text))

Index - Schema public


Table: public.backup_usr

public.backup_usr Structure
F-Key Name Type Description
usr_id integer
usr_username text
usr_propername text
usr_passwd text
usr_locale_id integer
usr_initials text
usr_agent boolean
usr_active boolean
usr_email text
usr_dept_id integer
usr_shift_id integer
usr_window text

Index - Schema public


Table: public.bankaccnt

Bank Account information

public.bankaccnt Structure
F-Key Name Type Description
bankaccnt_id serial PRIMARY KEY
bankaccnt_name text UNIQUE NOT NULL
bankaccnt_descrip text
bankaccnt_bankname text
bankaccnt_accntnumber text
bankaccnt_ar boolean
bankaccnt_ap boolean
bankaccnt_nextchknum integer
bankaccnt_type character(1)
bankaccnt_accnt_id integer
bankaccnt_check_form_id integer
bankaccnt_userec boolean
bankaccnt_rec_accnt_id integer
public.curr_symbol.curr_id bankaccnt_curr_id integer DEFAULT basecurrid()
bankaccnt_notes text
bankaccnt_routing text NOT NULL DEFAULT ''::text
bankaccnt_ach_enabled boolean NOT NULL DEFAULT false
bankaccnt_ach_origin text NOT NULL DEFAULT ''::text
bankaccnt_ach_genchecknum boolean NOT NULL DEFAULT false
bankaccnt_ach_leadtime integer
bankaccnt_ach_lastdate date
bankaccnt_ach_lastfileid character(1)
bankaccnt_ach_origintype text
bankaccnt_ach_originname text
bankaccnt_ach_desttype text
bankaccnt_ach_fed_dest text
bankaccnt_ach_destname text
bankaccnt_ach_dest text

 

public.bankaccnt Constraints
Name Constraint
bankaccnt_bankaccnt_name_check CHECK ((bankaccnt_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.bankadj

Bank Adjustments information

public.bankadj Structure
F-Key Name Type Description
bankadj_id serial PRIMARY KEY
bankadj_bankaccnt_id integer NOT NULL
bankadj_bankadjtype_id integer NOT NULL
bankadj_created timestamp without time zone NOT NULL DEFAULT now()
bankadj_username text NOT NULL DEFAULT geteffectivextuser()
bankadj_date date NOT NULL
bankadj_docnumber text
bankadj_amount numeric(10,2) NOT NULL
bankadj_notes text
bankadj_sequence integer
bankadj_posted boolean NOT NULL DEFAULT false
public.curr_symbol.curr_id bankadj_curr_id integer DEFAULT basecurrid()
bankadj_curr_rate numeric

Index - Schema public


Table: public.bankadjtype

Bank Adjustment Types information

public.bankadjtype Structure
F-Key Name Type Description
bankadjtype_id serial PRIMARY KEY
bankadjtype_name text UNIQUE NOT NULL
bankadjtype_descrip text
bankadjtype_accnt_id integer NOT NULL
bankadjtype_iscredit boolean NOT NULL DEFAULT false

 

public.bankadjtype Constraints
Name Constraint
bankadjtype_bankadjtype_name_check CHECK ((bankadjtype_name <> ''::text))

Index - Schema public


Table: public.bankrec

Bank Reconciliation posting history

public.bankrec Structure
F-Key Name Type Description
bankrec_id serial PRIMARY KEY
bankrec_created timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
bankrec_username text NOT NULL DEFAULT geteffectivextuser()
bankrec_bankaccnt_id integer
bankrec_opendate date
bankrec_enddate date
bankrec_openbal numeric(20,2)
bankrec_endbal numeric(20,2)
bankrec_posted boolean DEFAULT false
bankrec_postdate timestamp without time zone

Index - Schema public


Table: public.bankrecitem

Posted Bank Reconciliation Line Item information

public.bankrecitem Structure
F-Key Name Type Description
bankrecitem_id serial PRIMARY KEY
bankrecitem_bankrec_id integer NOT NULL
bankrecitem_source text NOT NULL
bankrecitem_source_id integer NOT NULL
bankrecitem_cleared boolean DEFAULT false
bankrecitem_curr_rate numeric
bankrecitem_amount numeric

Index - Schema public


Table: public.bomhead

Bill of Materials (BOM) header information

public.bomhead Structure
F-Key Name Type Description
bomhead_id integer PRIMARY KEY DEFAULT nextval(('"bomhead_bomhead_id_seq"'::text)::regclass)
public.item.item_id bomhead_item_id integer NOT NULL
bomhead_serial integer
bomhead_docnum text
bomhead_revision text
bomhead_revisiondate date
bomhead_batchsize numeric(18,6)
bomhead_requiredqtyper numeric(20,8)
bomhead_rev_id integer DEFAULT (-1)

 

public.bomhead Constraints
Name Constraint
bomhead_bomhead_batchsize_check CHECK ((bomhead_batchsize > (0)::numeric))

Index - Schema public


Table: public.bomitem

Bill of Materials (BOM) component Items information

public.bomitem Structure
F-Key Name Type Description
bomitem_id integer PRIMARY KEY DEFAULT nextval(('bomitem_bomitem_id_seq'::text)::regclass)
public.item.item_id bomitem_parent_item_id integer NOT NULL
bomitem_seqnumber integer
public.item.item_id bomitem_item_id integer NOT NULL
bomitem_qtyper numeric(20,8) NOT NULL
bomitem_scrap numeric(8,4) NOT NULL
bomitem_status character(1)
bomitem_effective date NOT NULL
bomitem_expires date NOT NULL
bomitem_createwo boolean NOT NULL
bomitem_issuemethod character(1) NOT NULL
bomitem_schedatwooper boolean NOT NULL
bomitem_ecn text
bomitem_moddate date
bomitem_subtype character(1) NOT NULL
public.uom.uom_id bomitem_uom_id integer NOT NULL
bomitem_rev_id integer DEFAULT (-1)
bomitem_booitem_seq_id integer DEFAULT (-1)
public.char.char_id bomitem_char_id integer
bomitem_value text
bomitem_notes text
bomitem_ref text
bomitem_qtyfxd numeric(20,8) NOT NULL

The fixed quantity required
bomitem_issuewo boolean NOT NULL DEFAULT false

 

public.bomitem Constraints
Name Constraint
bomitem_bomitem_issuemethod_check CHECK ((((bomitem_issuemethod = 'M'::bpchar) OR (bomitem_issuemethod = 'S'::bpchar)) OR (bomitem_issuemethod = 'L'::bpchar)))
bomitem_bomitem_subtype_check CHECK ((((bomitem_subtype = 'N'::bpchar) OR (bomitem_subtype = 'I'::bpchar)) OR (bomitem_subtype = 'B'::bpchar)))

Tables referencing this one via Foreign Key Constraints:

bomitem_bomitem_item_id_idx bomitem_item_id bomitem_effective_key bomitem_effective bomitem_expires_key bomitem_expires bomitem_parent_item_id bomitem_parent_item_id

Index - Schema public


Table: public.bomitemcost

Bomitem Cost information

public.bomitemcost Structure
F-Key Name Type Description
bomitemcost_id serial PRIMARY KEY
public.bomitem.bomitem_id bomitemcost_bomitem_id integer NOT NULL
public.costelem.costelem_id bomitemcost_costelem_id integer NOT NULL
bomitemcost_lowlevel boolean NOT NULL DEFAULT false
bomitemcost_stdcost numeric(16,6) NOT NULL
bomitemcost_posted date
bomitemcost_actcost numeric(16,6) NOT NULL
bomitemcost_updated date
public.curr_symbol.curr_id bomitemcost_curr_id integer NOT NULL DEFAULT basecurrid()
bomitemcost_bomitem_id_key bomitemcost_bomitem_id

Index - Schema public


Table: public.bomitemsub

Bill of Materials (BOM) defined Substitutions information

public.bomitemsub Structure
F-Key Name Type Description
bomitemsub_id serial PRIMARY KEY
public.bomitem.bomitem_id bomitemsub_bomitem_id integer NOT NULL
public.item.item_id bomitemsub_item_id integer NOT NULL
bomitemsub_uomratio numeric(20,10) NOT NULL
bomitemsub_rank integer NOT NULL

Index - Schema public


Table: public.bomwork

Temporary table for storing information requested by Bill of Materials (BOM) displays and reports

public.bomwork Structure
F-Key Name Type Description
bomwork_id serial PRIMARY KEY
bomwork_set_id integer
bomwork_seqnumber integer
bomwork_item_id integer
bomwork_item_type character(1)
bomwork_qtyper numeric(20,8)
bomwork_scrap numeric(20,10)
bomwork_status character(1)
bomwork_level integer
bomwork_parent_id integer
bomwork_effective date
bomwork_expires date
bomwork_stdunitcost numeric(16,6)
bomwork_actunitcost numeric(16,6)
bomwork_parent_seqnumber integer
bomwork_createwo boolean
bomwork_issuemethod character(1)
public.char.char_id bomwork_char_id integer
bomwork_value text
bomwork_notes text
bomwork_ref text
bomwork_bomitem_id integer
bomwork_ecn text
bomwork_qtyfxd numeric(20,8) NOT NULL

The fixed quantity required
bomwork_qtyreq numeric(20,8) NOT NULL

The total quantity required

Index - Schema public


View: public.budget

public.budget Structure
F-Key Name Type Description
budget_id integer
budget_period_id integer
budget_accnt_id integer
budget_amount numeric(20,4)
SELECT budgitem.budgitem_id AS budget_id
, budgitem.budgitem_period_id AS budget_period_id
, budgitem.budgitem_accnt_id AS budget_accnt_id
, budgitem.budgitem_amount AS budget_amount 
FROM budgitem;

Index - Schema public


Table: public.budghead

public.budghead Structure
F-Key Name Type Description
budghead_id serial PRIMARY KEY
budghead_name text UNIQUE NOT NULL
budghead_descrip text

 

public.budghead Constraints
Name Constraint
budghead_budghead_name_check CHECK ((budghead_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.budgitem

public.budgitem Structure
F-Key Name Type Description
budgitem_id serial PRIMARY KEY
public.budghead.budghead_id budgitem_budghead_id integer NOT NULL
public.period.period_id budgitem_period_id integer NOT NULL
budgitem_accnt_id integer NOT NULL
budgitem_amount numeric(20,4) NOT NULL

Index - Schema public


Table: public.calhead

Calendar header information

public.calhead Structure
F-Key Name Type Description
calhead_id integer PRIMARY KEY DEFAULT nextval(('"calhead_calhead_id_seq"'::text)::regclass)
calhead_type character(1)
calhead_name text NOT NULL
calhead_descrip text
calhead_origin character(1)

 

public.calhead Constraints
Name Constraint
calhead_calhead_name_check CHECK ((calhead_name <> ''::text))

Index - Schema public


Table: public.cashrcpt

Temporary table for storing Cash Receipt information before Cash Receipts are posted

public.cashrcpt Structure
F-Key Name Type Description
cashrcpt_id serial PRIMARY KEY
public.custinfo.cust_id cashrcpt_cust_id integer NOT NULL
cashrcpt_amount numeric(20,2) NOT NULL
cashrcpt_fundstype character(1) NOT NULL
cashrcpt_docnumber text
public.bankaccnt.bankaccnt_id cashrcpt_bankaccnt_id integer NOT NULL
cashrcpt_notes text
cashrcpt_distdate date DEFAULT ('now'::text)::date
cashrcpt_salescat_id integer DEFAULT (-1)
public.curr_symbol.curr_id cashrcpt_curr_id integer DEFAULT basecurrid()
cashrcpt_usecustdeposit boolean NOT NULL DEFAULT false
cashrcpt_void boolean NOT NULL DEFAULT false
cashrcpt_number text UNIQUE NOT NULL
cashrcpt_docdate date
cashrcpt_posted boolean NOT NULL DEFAULT false
cashrcpt_posteddate date
cashrcpt_postedby text
cashrcpt_applydate date
cashrcpt_discount numeric(20,2) NOT NULL DEFAULT 0.00
cashrcpt_curr_rate numeric NOT NULL

 

public.cashrcpt Constraints
Name Constraint
cashrcpt_cashrcpt_number_check CHECK ((cashrcpt_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cashrcptitem

Temporary table for storing information about applications of Cash Receipts before Cash Receipts are posted

public.cashrcptitem Structure
F-Key Name Type Description
cashrcptitem_id serial PRIMARY KEY
public.cashrcpt.cashrcpt_id cashrcptitem_cashrcpt_id integer NOT NULL
public.aropen.aropen_id cashrcptitem_aropen_id integer NOT NULL
cashrcptitem_amount numeric(20,2) NOT NULL
cashrcptitem_discount numeric(20,2) NOT NULL DEFAULT 0.00
cashrcptitem_applied boolean DEFAULT true

Index - Schema public


Table: public.cashrcptmisc

Cash Receipt Miscellaneous Application information

public.cashrcptmisc Structure
F-Key Name Type Description
cashrcptmisc_id serial PRIMARY KEY
public.cashrcpt.cashrcpt_id cashrcptmisc_cashrcpt_id integer NOT NULL
public.accnt.accnt_id cashrcptmisc_accnt_id integer NOT NULL
cashrcptmisc_amount numeric(20,2) NOT NULL
cashrcptmisc_notes text

Index - Schema public


Table: public.ccard

Credit Card Information - all bytea data is encrypted

public.ccard Structure
F-Key Name Type Description
ccard_id serial PRIMARY KEY
ccard_seq integer NOT NULL DEFAULT 10
public.custinfo.cust_id ccard_cust_id integer NOT NULL
ccard_active boolean DEFAULT true
ccard_name bytea
ccard_address1 bytea
ccard_address2 bytea
ccard_city bytea
ccard_state bytea
ccard_zip bytea
ccard_country bytea
ccard_number bytea
ccard_debit boolean DEFAULT false
ccard_month_expired bytea
ccard_year_expired bytea
ccard_type character(1) NOT NULL
ccard_date_added timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
ccard_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
ccard_added_by_username text NOT NULL DEFAULT geteffectivextuser()
ccard_last_updated_by_username text NOT NULL DEFAULT geteffectivextuser()
ccard_cust_id_idx ccard_cust_id

Index - Schema public


Table: public.ccardaud

Credit Card Information tracking data

public.ccardaud Structure
F-Key Name Type Description
ccardaud_id serial PRIMARY KEY
ccardaud_ccard_id integer
ccardaud_ccard_seq_old integer
ccardaud_ccard_seq_new integer
ccardaud_ccard_cust_id_old integer
ccardaud_ccard_cust_id_new integer
ccardaud_ccard_active_old boolean
ccardaud_ccard_active_new boolean
ccardaud_ccard_name_old bytea
ccardaud_ccard_name_new bytea
ccardaud_ccard_address1_old bytea
ccardaud_ccard_address1_new bytea
ccardaud_ccard_address2_old bytea
ccardaud_ccard_address2_new bytea
ccardaud_ccard_city_old bytea
ccardaud_ccard_city_new bytea
ccardaud_ccard_state_old bytea
ccardaud_ccard_state_new bytea
ccardaud_ccard_zip_old bytea
ccardaud_ccard_zip_new bytea
ccardaud_ccard_country_old bytea
ccardaud_ccard_country_new bytea
ccardaud_ccard_number_old bytea
ccardaud_ccard_number_new bytea
ccardaud_ccard_debit_old boolean
ccardaud_ccard_debit_new boolean
ccardaud_ccard_month_expired_old bytea
ccardaud_ccard_month_expired_new bytea
ccardaud_ccard_year_expired_old bytea
ccardaud_ccard_year_expired_new bytea
ccardaud_ccard_type_old character(1)
ccardaud_ccard_type_new character(1)
ccardaud_ccard_last_updated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
ccardaud_ccard_last_updated_by_username text NOT NULL DEFAULT geteffectivextuser()
ccardaud_ccard_cust_id_idx ccardaud_ccard_cust_id_new ccardaud_ccard_id_idx ccardaud_ccard_id

Index - Schema public


Table: public.ccbank

public.ccbank Structure
F-Key Name Type Description
ccbank_id serial PRIMARY KEY
ccbank_ccard_type text UNIQUE NOT NULL
public.bankaccnt.bankaccnt_id ccbank_bankaccnt_id integer

 

public.ccbank Constraints
Name Constraint
ccbank_ccbank_ccard_type_check CHECK ((ccbank_ccard_type = ANY (ARRAY['A'::text, 'D'::text, 'M'::text, 'P'::text, 'V'::text])))

Index - Schema public


Table: public.ccpay

Track Credit Card PAYments, although really this table tracs communications with Credit Card processing companies. Records in this table may progress from preauthorizations through captures to credits, or they may simply remain in their original state if there is no further processing.

public.ccpay Structure
F-Key Name Type Description
ccpay_id serial PRIMARY KEY

Internal ID of this ccpay record.
ccpay_ccard_id integer

Internal ID of the Credit Card used for this transaction.
ccpay_cust_id integer

Internal ID of the Customer owning the Credit Card
ccpay_amount numeric(20,2) NOT NULL DEFAULT 0.00

Actual amount of this transaction.
ccpay_auth boolean NOT NULL DEFAULT true

Boolean indicator of whether this transaction started out as a pre-authorization or not.
ccpay_status character(1) NOT NULL

The status of the last attempted transaction for this record. Values include A = Authorized, C = Charged, D = Declined or otherwise rejected, V = Voided, X = Error.
ccpay_type character(1) NOT NULL

The most recent type of transaction attempted with this record. Values include A = Authorize, C = Capture or Charge, R = cRedit, V = reVerse or Void.
ccpay_auth_charge character(1) NOT NULL

The original type of transaction attempted with this record. Values are the same as for ccpay_type.
ccpay_order_number text

The original xTuple ERP order for which this credit card transaction applies. This will usually be either a Sales Order number or Credit Memo number.
ccpay_order_number_seq integer

A sequence number to differentiate between different transactions for the same ccpay_order_number. For example, if a Customer makes a down payment and a final payment for a single order, there will be two distinct ccpay records with the same ccpay_order_number but different ccpay_order_number_seq values (1 and 2, respectively).
ccpay_r_avs text

The Address Verification System code returned by the credit card processing company.
ccpay_r_ordernum text

A transaction ID returned by the credit card processing company to be used when referring to this transaction later. It may be used for voiding, crediting, or capturing previous transactions.
ccpay_r_error text

Error message, if any, describing why this record failed to be processed properly.
ccpay_r_approved text

English text stating whether the transaction was approved, declined, hit an error, or was held for review. Specific values differ depending on the credit card processor.
ccpay_r_code text

The transaction Approval code returned by the credit card processor. Specific values differ depending on the credit card processor.
ccpay_r_message text

Additional text that describes the status of the transaction. This may be empty.
ccpay_yp_r_time timestamp without time zone

The time the transaction was posted according to the credit card processing company. May be blank.
ccpay_r_ref text

An additional reference number assigned to this transaction by the credit card processing company.
ccpay_yp_r_tdate text

The date the transaction was posted according to the credit card processing company. May be blank.
ccpay_r_tax text

[ deprecated ]
ccpay_r_shipping text

[ deprecated ]
ccpay_yp_r_score integer

A potential fraud score returned by the credit card company. May be blank.
ccpay_transaction_datetime timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone

The date and time this record was created, unless explicitly set by the application.
ccpay_by_username text NOT NULL DEFAULT geteffectivextuser()

The user who created this record, unless explicitly set by the application.
ccpay_curr_id integer DEFAULT basecurrid()

The internal ID of the currency of the ccpay_amount.
ccpay_ccpay_id integer

Foreign key to another ccpay record. This will have a value if a new ccpay record is created to record a Refund for part or all of another ccpay record.

Tables referencing this one via Foreign Key Constraints:

ccpay_ccard_id_idx ccpay_ccard_id ccpay_cust_id_idx ccpay_cust_id ccpay_order_number_idx ccpay_order_number

Index - Schema public


Table: public.char

Characteristic information

public.char Structure
F-Key Name Type Description
char_id serial PRIMARY KEY
char_name text UNIQUE NOT NULL
char_items boolean
char_options boolean
char_attributes boolean
char_lotserial boolean
char_notes text
char_customers boolean
char_crmaccounts boolean
char_addresses boolean
char_contacts boolean
char_opportunity boolean
char_employees boolean DEFAULT false
char_mask text
char_validator text
char_incidents boolean DEFAULT false
char_type integer NOT NULL
char_order integer NOT NULL
char_search boolean NOT NULL DEFAULT true

 

public.char Constraints
Name Constraint
char_char_name_check CHECK ((char_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.charass

Characteristic assignment information

public.charass Structure
F-Key Name Type Description
charass_id serial PRIMARY KEY
charass_target_type text
charass_target_id integer
charass_char_id integer
charass_value text
charass_default boolean NOT NULL DEFAULT false
charass_price numeric(16,4) NOT NULL
charass_target_idx charass_target_type, charass_target_id

Index - Schema public


Table: public.charopt

Stores list options for characteristics

public.charopt Structure
F-Key Name Type Description
charopt_id serial PRIMARY KEY

Primary key
public.char.char_id charopt_char_id integer

Reference to char table
charopt_value text NOT NULL

Option value
charopt_order integer NOT NULL

Option sort order

Index - Schema public


Table: public.checkhead

Accounts Payable Check Information

public.checkhead Structure
F-Key Name Type Description
checkhead_id serial PRIMARY KEY
checkhead_recip_id integer NOT NULL
checkhead_recip_type text NOT NULL
public.bankaccnt.bankaccnt_id checkhead_bankaccnt_id integer NOT NULL
checkhead_printed boolean NOT NULL DEFAULT false
checkhead_checkdate date NOT NULL
checkhead_number integer NOT NULL
checkhead_amount numeric(20,2) NOT NULL
checkhead_void boolean NOT NULL DEFAULT false
checkhead_replaced boolean NOT NULL DEFAULT false
checkhead_posted boolean NOT NULL DEFAULT false
checkhead_rec boolean NOT NULL DEFAULT false
checkhead_misc boolean NOT NULL DEFAULT false
public.expcat.expcat_id checkhead_expcat_id integer
checkhead_for text NOT NULL
checkhead_notes text NOT NULL
checkhead_journalnumber integer
public.curr_symbol.curr_id checkhead_curr_id integer NOT NULL DEFAULT basecurrid()
checkhead_deleted boolean NOT NULL DEFAULT false
checkhead_ach_batch text
checkhead_curr_rate numeric NOT NULL

 

public.checkhead Constraints
Name Constraint
checkhead_checkhead_amount_check CHECK ((checkhead_amount > (0)::numeric))
checkhead_checkhead_recip_type_check CHECK ((((checkhead_recip_type = 'C'::text) OR (checkhead_recip_type = 'V'::text)) OR (checkhead_recip_type = 'T'::text)))

Tables referencing this one via Foreign Key Constraints:

checkhead_posted_idx checkhead_posted checkhead_replaced_idx checkhead_replaced

Index - Schema public


Table: public.checkitem

Accounts Payable Check Line Item Information

public.checkitem Structure
F-Key Name Type Description
checkitem_id serial PRIMARY KEY
public.checkhead.checkhead_id checkitem_checkhead_id integer NOT NULL
checkitem_amount numeric(20,2) NOT NULL DEFAULT 0.0
checkitem_discount numeric(20,2) NOT NULL DEFAULT 0.0
checkitem_ponumber text
checkitem_vouchernumber text
checkitem_invcnumber text
public.apopen.apopen_id checkitem_apopen_id integer
public.aropen.aropen_id checkitem_aropen_id integer
checkitem_docdate date
public.curr_symbol.curr_id checkitem_curr_id integer NOT NULL DEFAULT basecurrid()
checkitem_cmnumber text
checkitem_ranumber text
checkitem_curr_rate numeric

 

public.checkitem Constraints
Name Constraint
checkitem_check CHECK ((NOT ((checkitem_apopen_id IS NOT NULL) AND (checkitem_aropen_id IS NOT NULL))))
checkitem_apopenitem_id_idx checkitem_apopen_id

Index - Schema public


View: public.checkrecip

public.checkrecip Structure
F-Key Name Type Description
checkrecip_id integer
checkrecip_type text
checkrecip_number text
checkrecip_name text
checkrecip_gltrans_source text
checkrecip_accnt_id integer
checkrecip_addr_id integer
(
SELECT custinfo.cust_id AS checkrecip_id
     ,'C' AS checkrecip_type
     , custinfo.cust_number AS checkrecip_number
     , custinfo.cust_name AS checkrecip_name
     ,'A/R' AS checkrecip_gltrans_source
     , findaraccount
     (custinfo.cust_id) AS checkrecip_accnt_id
     , cntct.cntct_addr_id AS checkrecip_addr_id 
  FROM (custinfo 
   LEFT JOIN cntct 
          ON (
                 (custinfo.cust_cntct_id = cntct.cntct_id)
           )
     )
UNION ALLSELECT taxauth.taxauth_id AS checkrecip_id
     ,'T' AS checkrecip_type
     , taxauth.taxauth_code AS checkrecip_number
     , taxauth.taxauth_name AS checkrecip_name
     ,'G/L' AS checkrecip_gltrans_source
     , taxauth.taxauth_accnt_id AS checkrecip_accnt_id
     , taxauth.taxauth_addr_id AS checkrecip_addr_id 
  FROM taxauth
)
UNION ALLSELECT vendinfo.vend_id AS checkrecip_id
,'V' AS checkrecip_type
, vendinfo.vend_number AS checkrecip_number
, vendinfo.vend_name AS checkrecip_name
,'A/P' AS checkrecip_gltrans_source
, findapaccount
(vendinfo.vend_id) AS checkrecip_accnt_id
, vendaddrinfo.vendaddr_addr_id AS checkrecip_addr_id 
FROM (vendinfo 
LEFT JOIN vendaddrinfo 
    ON (
           (
                 (vendinfo.vend_id = vendaddrinfo.vendaddr_vend_id)
               AND (upper
                       (vendaddrinfo.vendaddr_code) = 'REMIT'::text
                 )
           )
     )
);

Index - Schema public


Table: public.classcode

Class Code information

public.classcode Structure
F-Key Name Type Description
classcode_id integer PRIMARY KEY DEFAULT nextval(('classcode_classcode_id_seq'::text)::regclass)
classcode_code text UNIQUE NOT NULL
classcode_descrip text
classcode_mfg boolean
classcode_creator text
classcode_created timestamp without time zone
classcode_modifier text
classcode_modified timestamp without time zone
classcode_type text

 

public.classcode Constraints
Name Constraint
classcode_classcode_code_check CHECK ((classcode_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cmd

Custom menu command table.

public.cmd Structure
F-Key Name Type Description
cmd_id serial PRIMARY KEY
cmd_module text NOT NULL
cmd_title text NOT NULL
cmd_descrip text
cmd_privname text
cmd_executable text NOT NULL
cmd_name text

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cmdarg

Command argument for custom menu command table.

public.cmdarg Structure
F-Key Name Type Description
cmdarg_id serial PRIMARY KEY
public.cmd.cmd_id cmdarg_cmd_id integer NOT NULL
cmdarg_order integer NOT NULL
cmdarg_arg text NOT NULL

Index - Schema public


Table: public.cmhead

S/O Credit Memo header information

public.cmhead Structure
F-Key Name Type Description
cmhead_id integer PRIMARY KEY DEFAULT nextval(('cmhead_cmhead_id_seq'::text)::regclass)
cmhead_number text UNIQUE NOT NULL
cmhead_posted boolean
cmhead_invcnumber text
cmhead_custponumber text
public.custinfo.cust_id cmhead_cust_id integer
cmhead_docdate date
cmhead_shipto_id integer
cmhead_shipto_name text
cmhead_shipto_address1 text
cmhead_shipto_address2 text
cmhead_shipto_address3 text
cmhead_shipto_city text
cmhead_shipto_state text
cmhead_shipto_zipcode text
public.salesrep.salesrep_id cmhead_salesrep_id integer
cmhead_freight numeric(16,4)
cmhead_misc numeric(16,4)
cmhead_comments text
cmhead_printed boolean
cmhead_billtoname text
cmhead_billtoaddress1 text
cmhead_billtoaddress2 text
cmhead_billtoaddress3 text
cmhead_billtocity text
cmhead_billtostate text
cmhead_billtozip text
cmhead_hold boolean
cmhead_commission numeric(8,4)
cmhead_misc_accnt_id integer
cmhead_misc_descrip text
cmhead_rsncode_id integer
public.curr_symbol.curr_id cmhead_curr_id integer DEFAULT basecurrid()
public.taxtype.taxtype_id cmhead_freighttaxtype_id integer

Deprecated column - DO NOT USE
cmhead_gldistdate date
cmhead_billtocountry text
cmhead_shipto_country text
cmhead_rahead_id integer
public.taxzone.taxzone_id cmhead_taxzone_id integer
public.prj.prj_id cmhead_prj_id integer
cmhead_void boolean DEFAULT false
public.saletype.saletype_id cmhead_saletype_id integer

Associated sale type for credit memo.
public.shipzone.shipzone_id cmhead_shipzone_id integer

Associated shipping zone for credit memo.

 

public.cmhead Constraints
Name Constraint
cmhead_cmhead_number_check CHECK ((cmhead_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

cmhead_invcnumber_idx cmhead_invcnumber

Index - Schema public


Table: public.cmheadtax

public.cmheadtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.cmhead.cmhead_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.cmheadtax Inherits taxhist,

Index - Schema public


Table: public.cmitem

S/O Credit Memo Line Item information

public.cmitem Structure
F-Key Name Type Description
cmitem_id integer PRIMARY KEY DEFAULT nextval(('cmitem_cmitem_id_seq'::text)::regclass)
public.cmhead.cmhead_id cmitem_cmhead_id integer UNIQUE#1 NOT NULL
cmitem_linenumber integer UNIQUE#1 NOT NULL
cmitem_itemsite_id integer NOT NULL
cmitem_qtycredit numeric(18,6) NOT NULL
cmitem_qtyreturned numeric(18,6) NOT NULL
cmitem_unitprice numeric(16,4) NOT NULL
cmitem_comments text
cmitem_rsncode_id integer
public.taxtype.taxtype_id cmitem_taxtype_id integer
public.uom.uom_id cmitem_qty_uom_id integer NOT NULL
cmitem_qty_invuomratio numeric(20,10) NOT NULL
public.uom.uom_id cmitem_price_uom_id integer NOT NULL
cmitem_price_invuomratio numeric(20,10) NOT NULL
cmitem_raitem_id integer
cmitem_updateinv boolean NOT NULL DEFAULT true

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cmitemtax

public.cmitemtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.cmitem.cmitem_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.cmitemtax Inherits taxhist,

Index - Schema public


Table: public.cmnttype

Comment Type information

public.cmnttype Structure
F-Key Name Type Description
cmnttype_id serial PRIMARY KEY
cmnttype_name text UNIQUE NOT NULL
cmnttype_descrip text NOT NULL
cmnttype_usedin text
cmnttype_sys boolean NOT NULL DEFAULT false
cmnttype_editable boolean NOT NULL DEFAULT false
cmnttype_order integer

 

public.cmnttype Constraints
Name Constraint
cmnttype_cmnttype_name_check CHECK ((cmnttype_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cmnttypesource

Comment Type/Source association

public.cmnttypesource Structure
F-Key Name Type Description
cmnttypesource_id serial PRIMARY KEY
cmnttypesource_cmnttype_id integer
cmnttypesource_source_id integer

Index - Schema public


Table: public.cntct

Contact - information on how to reach a living person

public.cntct Structure
F-Key Name Type Description
cntct_id serial PRIMARY KEY
public.crmacct.crmacct_id cntct_crmacct_id integer
public.addr.addr_id cntct_addr_id integer
cntct_first_name text
cntct_last_name text
cntct_honorific text
cntct_initials text
cntct_active boolean DEFAULT true
cntct_phone text
cntct_phone2 text
cntct_fax text
cntct_email text
cntct_webaddr text
cntct_notes text
cntct_title text
cntct_number text UNIQUE NOT NULL
cntct_middle text
cntct_suffix text
cntct_owner_username text
cntct_name text

Tables referencing this one via Foreign Key Constraints:

cntct_email_idx cntct_email cntct_name_idx cntct_name

Index - Schema public


Table: public.cntctaddr

public.cntctaddr Structure
F-Key Name Type Description
cntctaddr_id serial PRIMARY KEY
public.cntct.cntct_id cntctaddr_cntct_id integer
cntctaddr_primary boolean NOT NULL
public.addr.addr_id cntctaddr_addr_id integer NOT NULL
cntctaddr_type character(2) NOT NULL

Index - Schema public


Table: public.cntctdata

public.cntctdata Structure
F-Key Name Type Description
cntctdata_id serial PRIMARY KEY
public.cntct.cntct_id cntctdata_cntct_id integer
cntctdata_primary boolean NOT NULL
cntctdata_text text NOT NULL
cntctdata_type character(2) NOT NULL

Index - Schema public


Table: public.cntcteml

Stores email addresses for contacts

public.cntcteml Structure
F-Key Name Type Description
cntcteml_id serial PRIMARY KEY

Primary key
public.cntct.cntct_id cntcteml_cntct_id integer

Reference to contact table
cntcteml_primary boolean NOT NULL DEFAULT false

Flags whether this is the primary email address
cntcteml_email text NOT NULL

Alternate information

Index - Schema public


Table: public.cntctmrgd

public.cntctmrgd Structure
F-Key Name Type Description
public.cntct.cntct_id cntctmrgd_cntct_id integer PRIMARY KEY
cntctmrgd_error boolean DEFAULT false

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.cntctsel

public.cntctsel Structure
F-Key Name Type Description
public.cntct.cntct_id cntctsel_cntct_id integer PRIMARY KEY
cntctsel_target boolean
cntctsel_mrg_crmacct_id boolean DEFAULT false
cntctsel_mrg_addr_id boolean DEFAULT false
cntctsel_mrg_first_name boolean DEFAULT false
cntctsel_mrg_last_name boolean DEFAULT false
cntctsel_mrg_honorific boolean DEFAULT false
cntctsel_mrg_initials boolean DEFAULT false
cntctsel_mrg_phone boolean DEFAULT false
cntctsel_mrg_phone2 boolean DEFAULT false
cntctsel_mrg_fax boolean DEFAULT false
cntctsel_mrg_email boolean DEFAULT false
cntctsel_mrg_webaddr boolean DEFAULT false
cntctsel_mrg_notes boolean DEFAULT false
cntctsel_mrg_title boolean DEFAULT false
cntctsel_mrg_middle boolean DEFAULT false
cntctsel_mrg_suffix boolean DEFAULT false
cntctsel_mrg_owner_username boolean DEFAULT false

Index - Schema public


Table: public.cntslip

Count Slip information

public.cntslip Structure
F-Key Name Type Description
cntslip_id integer PRIMARY KEY DEFAULT nextval(('"cntslip_cntslip_id_seq"'::text)::regclass)
cntslip_cnttag_id integer
cntslip_entered timestamp with time zone
cntslip_posted boolean
cntslip_number text
cntslip_qty numeric(18,6)
cntslip_comments text
cntslip_location_id integer
cntslip_lotserial text
cntslip_lotserial_expiration date
cntslip_lotserial_warrpurc date
cntslip_username text

Index - Schema public


Table: public.cobill

Billing Selection Line Item information

public.cobill Structure
F-Key Name Type Description
cobill_id integer PRIMARY KEY DEFAULT nextval(('cobill_cobill_id_seq'::text)::regclass)
cobill_coitem_id integer
cobill_selectdate timestamp with time zone
cobill_qty numeric(18,6)
cobill_invcnum integer
cobill_toclose boolean
cobill_cobmisc_id integer
cobill_select_username text
public.invcitem.invcitem_id cobill_invcitem_id integer
public.taxtype.taxtype_id cobill_taxtype_id integer

Tables referencing this one via Foreign Key Constraints:

cobill_cobmisc_id cobill_cobmisc_id cobill_coitem_id cobill_coitem_id

Index - Schema public


Table: public.cobilltax

public.cobilltax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.cobill.cobill_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.cobilltax Inherits taxhist,

Index - Schema public


Table: public.cobmisc

General information about Billing Selections

public.cobmisc Structure
F-Key Name Type Description
cobmisc_id integer PRIMARY KEY DEFAULT nextval(('cobmisc_cobmisc_id_seq'::text)::regclass)
cobmisc_cohead_id integer
cobmisc_shipvia text
cobmisc_freight numeric(16,4)
cobmisc_misc numeric(16,4)
cobmisc_payment numeric(16,4)
cobmisc_paymentref text
cobmisc_notes text
cobmisc_shipdate date
cobmisc_invcnumber integer
cobmisc_invcdate date
cobmisc_posted boolean
cobmisc_misc_accnt_id integer
cobmisc_misc_descrip text
cobmisc_closeorder boolean
public.curr_symbol.curr_id cobmisc_curr_id integer DEFAULT basecurrid()
public.invchead.invchead_id cobmisc_invchead_id integer
public.taxzone.taxzone_id cobmisc_taxzone_id integer
public.taxtype.taxtype_id cobmisc_taxtype_id integer

Tables referencing this one via Foreign Key Constraints:

cobmisc_cohead_id cobmisc_cohead_id cobmisc_posted cobmisc_posted

Index - Schema public


Table: public.cobmisctax

public.cobmisctax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.cobmisc.cobmisc_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.cobmisctax Inherits taxhist,

Index - Schema public


Table: public.cohead

Sales Order header information

public.cohead Structure
F-Key Name Type Description
cohead_id integer PRIMARY KEY DEFAULT nextval(('cohead_cohead_id_seq'::text)::regclass)
cohead_number text UNIQUE NOT NULL
public.custinfo.cust_id cohead_cust_id integer NOT NULL
cohead_custponumber text
cohead_type character(1)
cohead_orderdate date
public.whsinfo.warehous_id cohead_warehous_id integer
public.shiptoinfo.shipto_id cohead_shipto_id integer
cohead_shiptoname text
cohead_shiptoaddress1 text
cohead_shiptoaddress2 text
cohead_shiptoaddress3 text
cohead_shiptoaddress4 text
cohead_shiptoaddress5 text
public.salesrep.salesrep_id cohead_salesrep_id integer NOT NULL
public.terms.terms_id cohead_terms_id integer NOT NULL
cohead_origin character(1)
cohead_fob text
cohead_shipvia text
cohead_shiptocity text
cohead_shiptostate text
cohead_shiptozipcode text
cohead_freight numeric(16,4) NOT NULL
cohead_misc numeric(16,4) NOT NULL
cohead_imported boolean DEFAULT false
cohead_ordercomments text
cohead_shipcomments text
cohead_shiptophone text
cohead_shipchrg_id integer
public.shipform.shipform_id cohead_shipform_id integer
cohead_billtoname text
cohead_billtoaddress1 text
cohead_billtoaddress2 text
cohead_billtoaddress3 text
cohead_billtocity text
cohead_billtostate text
cohead_billtozipcode text
public.accnt.accnt_id cohead_misc_accnt_id integer
cohead_misc_descrip text
cohead_commission numeric(16,4)
cohead_miscdate date
cohead_holdtype character(1)
cohead_packdate date
public.prj.prj_id cohead_prj_id integer
cohead_wasquote boolean NOT NULL DEFAULT false
cohead_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
cohead_shipcomplete boolean NOT NULL DEFAULT false
cohead_created timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone
cohead_creator text DEFAULT geteffectivextuser()
cohead_quote_number text
cohead_billtocountry text
cohead_shiptocountry text
public.curr_symbol.curr_id cohead_curr_id integer DEFAULT basecurrid()
cohead_calcfreight boolean NOT NULL DEFAULT false
public.cntct.cntct_id cohead_shipto_cntct_id integer
cohead_shipto_cntct_honorific text
cohead_shipto_cntct_first_name text
cohead_shipto_cntct_middle text
cohead_shipto_cntct_last_name text
cohead_shipto_cntct_suffix text
cohead_shipto_cntct_phone text
cohead_shipto_cntct_title text
cohead_shipto_cntct_fax text
cohead_shipto_cntct_email text
public.cntct.cntct_id cohead_billto_cntct_id integer
cohead_billto_cntct_honorific text
cohead_billto_cntct_first_name text
cohead_billto_cntct_middle text
cohead_billto_cntct_last_name text
cohead_billto_cntct_suffix text
cohead_billto_cntct_phone text
cohead_billto_cntct_title text
cohead_billto_cntct_fax text
cohead_billto_cntct_email text
public.taxzone.taxzone_id cohead_taxzone_id integer
public.taxtype.taxtype_id cohead_taxtype_id integer
public.ophead.ophead_id cohead_ophead_id integer
cohead_status character(1) NOT NULL DEFAULT 'O'::bpchar
public.saletype.saletype_id cohead_saletype_id integer

Associated sale type for sales order.
public.shipzone.shipzone_id cohead_shipzone_id integer

Associated shipping zone for sales order.

 

public.cohead Constraints
Name Constraint
cohead_check CHECK (((cohead_misc = (0)::numeric) OR ((cohead_misc <> (0)::numeric) AND (cohead_misc_accnt_id IS NOT NULL))))
cohead_cohead_number_check CHECK ((cohead_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

cohead_cohead_status_idx cohead_status cohead_cust_id_key cohead_cust_id cohead_custponumber_idx cohead_custponumber cohead_shipto_id cohead_shipto_id

Index - Schema public


Table: public.cohist

Sales Order history

public.cohist Structure
F-Key Name Type Description
cohist_id integer PRIMARY KEY DEFAULT nextval(('cohist_cohist_id_seq'::text)::regclass)
public.custinfo.cust_id cohist_cust_id integer
cohist_itemsite_id integer
cohist_shipdate date
cohist_shipvia text
cohist_ordernumber text
cohist_orderdate date
cohist_invcnumber text
cohist_invcdate date
cohist_qtyshipped numeric(18,6)
cohist_unitprice numeric(16,4)
cohist_shipto_id integer
public.salesrep.salesrep_id cohist_salesrep_id integer
cohist_duedate date
cohist_imported boolean DEFAULT false
cohist_billtoname text
cohist_billtoaddress1 text
cohist_billtoaddress2 text
cohist_billtoaddress3 text
cohist_billtocity text
cohist_billtostate text
cohist_billtozip text
cohist_shiptoname text
cohist_shiptoaddress1 text
cohist_shiptoaddress2 text
cohist_shiptoaddress3 text
cohist_shiptocity text
cohist_shiptostate text
cohist_shiptozip text
cohist_commission numeric(16,4)
cohist_commissionpaid boolean
cohist_unitcost numeric(18,6)
cohist_misc_type character(1)
cohist_misc_descrip text
cohist_misc_id integer
cohist_doctype text
cohist_promisedate date
cohist_ponumber text
public.curr_symbol.curr_id cohist_curr_id integer DEFAULT basecurrid()
cohist_sequence integer
public.taxtype.taxtype_id cohist_taxtype_id integer
public.taxzone.taxzone_id cohist_taxzone_id integer
public.ccpay.ccpay_id cohist_cohead_ccpay_id integer

Credit card payments made at sales order time (as opposed to invoice time) need special treatment. This field allows checking for this case.
cohist_saletype_id integer

Associated sale type for sales history.
cohist_shipzone_id integer

Associated shipping zone for sales history.

Tables referencing this one via Foreign Key Constraints:

cohist_cust_id cohist_cust_id cohist_invcnumber cohist_invcnumber cohist_itemsite_id cohist_itemsite_id cohist_shipdate cohist_shipdate cohist_shipto_id cohist_shipto_id

Index - Schema public


Table: public.cohisttax

public.cohisttax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.cohist.cohist_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.cohisttax Inherits taxhist,

Index - Schema public


Table: public.coitem

Sales Order Line Item information

public.coitem Structure
F-Key Name Type Description
coitem_id integer PRIMARY KEY DEFAULT nextval(('coitem_coitem_id_seq'::text)::regclass)
public.cohead.cohead_id coitem_cohead_id integer
coitem_linenumber integer NOT NULL
public.itemsite.itemsite_id coitem_itemsite_id integer
coitem_status character(1)
coitem_scheddate date
coitem_promdate date
coitem_qtyord numeric(18,6) NOT NULL
coitem_unitcost numeric(16,6) NOT NULL
coitem_price numeric(16,4) NOT NULL
coitem_custprice numeric(16,4) NOT NULL
coitem_qtyshipped numeric(18,6) NOT NULL
coitem_order_id integer
coitem_memo text
coitem_imported boolean DEFAULT false
coitem_qtyreturned numeric(18,6)
coitem_closedate timestamp with time zone
coitem_custpn text
coitem_order_type character(1)
coitem_close_username text
coitem_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
public.item.item_id coitem_substitute_item_id integer
coitem_created timestamp without time zone DEFAULT ('now'::text)::timestamp(6) with time zone
coitem_creator text DEFAULT geteffectivextuser()
coitem_prcost numeric(16,6)
public.uom.uom_id coitem_qty_uom_id integer NOT NULL
coitem_qty_invuomratio numeric(20,10) NOT NULL
public.uom.uom_id coitem_price_uom_id integer NOT NULL
coitem_price_invuomratio numeric(20,10) NOT NULL
coitem_warranty boolean NOT NULL DEFAULT false
public.accnt.accnt_id coitem_cos_accnt_id integer
coitem_qtyreserved numeric(18,6) NOT NULL DEFAULT 0.0
coitem_subnumber integer NOT NULL
coitem_firm boolean NOT NULL DEFAULT false
public.taxtype.taxtype_id coitem_taxtype_id integer
public.accnt.accnt_id coitem_rev_accnt_id integer
coitem_pricemode character(1) NOT NULL DEFAULT 'D'::bpchar

Pricing mode for sales order item. Valid values are D-discount, and M-markup

 

public.coitem Constraints
Name Constraint
coitem_coitem_status_check CHECK ((((coitem_status = 'O'::bpchar) OR (coitem_status = 'C'::bpchar)) OR (coitem_status = 'X'::bpchar)))
valid_coitem_pricemode CHECK ((coitem_pricemode = ANY (ARRAY['D'::bpchar, 'M'::bpchar])))
coitem_cohead_id_key coitem_cohead_id coitem_itemsite_id coitem_itemsite_id coitem_linenumber_key coitem_linenumber coitem_status_key coitem_status

Index - Schema public


Table: public.comment

Comment information

public.comment Structure
F-Key Name Type Description
comment_id integer PRIMARY KEY DEFAULT nextval(('"comment_comment_id_seq"'::text)::regclass)
comment_source_id integer
comment_date timestamp with time zone
comment_user text
comment_text text
public.cmnttype.cmnttype_id comment_cmnttype_id integer
comment_source text
comment_public boolean
comment_comment_source_idx comment_source, comment_source_id

Index - Schema public


Table: public.company

Company information

public.company Structure
F-Key Name Type Description
company_id serial PRIMARY KEY
company_number text UNIQUE NOT NULL
company_descrip text
company_external boolean NOT NULL DEFAULT false
company_server text
company_port integer
company_database text
public.curr_symbol.curr_id company_curr_id integer
public.accnt.accnt_id company_yearend_accnt_id integer
public.accnt.accnt_id company_gainloss_accnt_id integer
public.accnt.accnt_id company_dscrp_accnt_id integer
public.accnt.accnt_id company_unrlzgainloss_accnt_id integer

 

public.company Constraints
Name Constraint
company_company_number_check CHECK ((company_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.contrct

Grouping of Item Sources for a Vendor with common effective and expiration dates.

public.contrct Structure
F-Key Name Type Description
contrct_id serial PRIMARY KEY

Sequence identifier for contract.
contrct_number text NOT NULL

User defined identifier for contract.
public.vendinfo.vend_id contrct_vend_id integer NOT NULL

Vendor associated with contract.
contrct_descrip text

Description for contract.
contrct_effective date NOT NULL

Effective date for contract. Constraint for overlap.
contrct_expires date NOT NULL

Expiration date for contract. Constraint for overlap.
contrct_note text

Notes for contract.

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.costcat

Cost Category information

public.costcat Structure
F-Key Name Type Description
costcat_id integer PRIMARY KEY DEFAULT nextval(('costcat_costcat_id_seq'::text)::regclass)
costcat_code text UNIQUE NOT NULL
costcat_descrip text
costcat_asset_accnt_id integer
costcat_liability_accnt_id integer
costcat_adjustment_accnt_id integer
costcat_matusage_accnt_id integer
costcat_purchprice_accnt_id integer
costcat_laboroverhead_accnt_id integer
costcat_scrap_accnt_id integer
costcat_invcost_accnt_id integer
costcat_wip_accnt_id integer
costcat_shipasset_accnt_id integer
costcat_mfgscrap_accnt_id integer
costcat_transform_accnt_id integer
costcat_freight_accnt_id integer
costcat_toliability_accnt_id integer
costcat_exp_accnt_id integer

 

public.costcat Constraints
Name Constraint
costcat_costcat_code_check CHECK ((costcat_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.costelem

Costing Element information

public.costelem Structure
F-Key Name Type Description
costelem_id integer PRIMARY KEY DEFAULT nextval(('costelem_costelem_id_seq'::text)::regclass)
costelem_type text UNIQUE NOT NULL
costelem_sys boolean
costelem_po boolean
costelem_active boolean
costelem_exp_accnt_id integer
costelem_cost_item_id integer

 

public.costelem Constraints
Name Constraint
costelem_costelem_type_check CHECK ((costelem_type <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.costhist

Item Cost history

public.costhist Structure
F-Key Name Type Description
costhist_id integer PRIMARY KEY DEFAULT nextval(('"costhist_costhist_id_seq"'::text)::regclass)
costhist_item_id integer
costhist_costelem_id integer
costhist_type character(1)
costhist_date timestamp with time zone
costhist_oldcost numeric(16,6)
costhist_newcost numeric(16,6)
costhist_lowlevel boolean
public.curr_symbol.curr_id costhist_oldcurr_id integer DEFAULT basecurrid()
public.curr_symbol.curr_id costhist_newcurr_id integer DEFAULT basecurrid()
costhist_username text

Index - Schema public


Table: public.costupdate

Scratch area for sequencing the updating of item costs

public.costupdate Structure
F-Key Name Type Description
costupdate_item_id integer UNIQUE
costupdate_lowlevel_code integer NOT NULL DEFAULT 1
costupdate_item_type character(1)

Index - Schema public


Table: public.country

Basic information and properties about countries.

public.country Structure
F-Key Name Type Description
country_id serial PRIMARY KEY
country_abbr character(2) UNIQUE
country_name text UNIQUE
country_curr_abbr character(3)
country_curr_name text
country_curr_number character(3)
country_curr_symbol character varying(9)
country_qt_number integer

 

public.country Constraints
Name Constraint
country_country_abbr_check CHECK ((country_abbr <> ''::bpchar))
country_country_name_check CHECK ((country_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


View: public.creditmemoeditlist

public.creditmemoeditlist Structure
F-Key Name Type Description
orderid integer
itemid integer
documentnumber text
cust_number text
billtoname text
ordernumber text
linenumber integer
item text
itemdescrip text
iteminvuom text
qtytobill text
price text
extprice text
sence text
account text
(
     (
           (
                 (
                  SELECT cmhead.cmhead_id AS orderid
                       , (-2) AS itemid
                       , ('C/M-'::text || formatcreditmemonumber
                             (cmhead.cmhead_id)
                       ) AS documentnumber
                       , custinfo.cust_number
                       , cmhead.cmhead_billtoname AS billtoname
                       , cmhead.cmhead_number AS ordernumber
                       , (-1) AS linenumber
                       ,'' AS item
                       ,'' AS itemdescrip
                       ,'' AS iteminvuom
                       ,'' AS qtytobill
                       ,'' AS price
                       , formatmoney
                       (
                             (
                                   (
                                         (calccmheadamt
                                               (cmhead.cmhead_id) + cmhead.cmhead_freight
                                         ) + cmhead.cmhead_misc
                                   ) + calccmheadtax
                                   (cmhead.cmhead_id)
                             )
                       ) AS extprice
                       ,'Credit' AS sence
                       , COALESCE
                       (
                             (
                              SELECT formatglaccountlong
                                   (accnt.accnt_id) AS formatglaccountlong 
                                FROM accnt 
                               WHERE (accnt.accnt_id = findaraccount
                                         (custinfo.cust_id)
                                   )
                             )
                             ,'Not Assigned'::text
                       ) AS account 
                    FROM custinfo
                       , cmhead 
                   WHERE (
                             (
                                   (
                                         (cmhead.cmhead_cust_id = custinfo.cust_id)
                                       AND (cmhead.cmhead_cust_id = custinfo.cust_id)
                                   )
                                 AND (NOT cmhead.cmhead_posted)
                             )
                           AND (NOT cmhead.cmhead_hold)
                       )
                   UNIONSELECT cmhead.cmhead_id AS orderid
                       , (-1) AS itemid
                       ,'' AS documentnumber
                       ,'' AS cust_number
                       ,'' AS billtoname
                       , cmhead.cmhead_number AS ordernumber
                       , (-1) AS linenumber
                       ,'Freight' AS item
                       ,'Freight Charge' AS itemdescrip
                       ,'' AS iteminvuom
                       ,'' AS qtytobill
                       , formatmoney
                       (cmhead.cmhead_freight) AS price
                       , formatmoney
                       (cmhead.cmhead_freight) AS extprice
                       ,'Debit' AS sence
                       , CASE WHEN 
                       (accnt.accnt_id IS NULL) THEN 'Not Assigned'::text ELSE formatglaccountlong
                       (accnt.accnt_id) END AS account 
                    FROM (cmhead 
                     LEFT JOIN accnt 
                            ON (
                                   (accnt.accnt_id = findfreightaccount
                                         (cmhead.cmhead_cust_id)
                                   )
                             )
                       )
                   WHERE (
                             (
                                   (NOT cmhead.cmhead_posted)
                                 AND (NOT cmhead.cmhead_hold)
                             )
                           AND (cmhead.cmhead_freight <> 
                                   (0)::numeric
                             )
                       )
                 )
             UNIONSELECT cmhead.cmhead_id AS orderid
                 , (-1) AS itemid
                 ,'' AS documentnumber
                 ,'' AS cust_number
                 ,'' AS billtoname
                 , cmhead.cmhead_number AS ordernumber
                 , (-1) AS linenumber
                 ,'Misc. Charge' AS item
                 , cmhead.cmhead_misc_descrip AS itemdescrip
                 ,'' AS iteminvuom
                 ,'' AS qtytobill
                 , formatmoney
                 (cmhead.cmhead_misc) AS price
                 , formatmoney
                 (cmhead.cmhead_misc) AS extprice
                 ,'Debit' AS sence
                 , formatglaccountlong
                 (cmhead.cmhead_misc_accnt_id) AS account 
              FROM cmhead 
             WHERE (
                       (
                             (NOT cmhead.cmhead_posted)
                           AND (NOT cmhead.cmhead_hold)
                       )
                     AND (cmhead.cmhead_misc <> 
                             (0)::numeric
                       )
                 )
           )
       UNIONSELECT cmhead.cmhead_id AS orderid
           , (-1) AS itemid
           ,'' AS documentnumber
           ,'' AS cust_number
           ,'' AS billtoname
           , cmhead.cmhead_number AS ordernumber
           , (-1) AS linenumber
           ,'Sales Tax' AS item
           , tax.tax_descrip AS itemdescrip
           ,'' AS iteminvuom
           ,'' AS qtytobill
           , formatmoney
           (
                 (cmheadtax.taxhist_tax * 
                       (-1.0)
                 )
           ) AS price
           , formatmoney
           (
                 (cmheadtax.taxhist_tax * 
                       (-1.0)
                 )
           ) AS extprice
           ,'Debit' AS sence
           , CASE WHEN 
           (accnt.accnt_id IS NULL) THEN 'Not Assigned'::text ELSE 
           (
                 (formatglaccountlong
                       (accnt.accnt_id) || ' - '::text
                 ) || accnt.accnt_descrip
           ) END AS account 
        FROM (
                 (
                       (cmhead 
                          JOIN cmheadtax 
                            ON (
                                   (cmheadtax.taxhist_parent_id = cmhead.cmhead_id)
                             )
                       )
                    JOIN tax 
                      ON (
                             (tax.tax_id = cmheadtax.taxhist_tax_id)
                       )
                 )
         LEFT JOIN accnt 
                ON (
                       (accnt.accnt_id = tax.tax_sales_accnt_id)
                 )
           )
       WHERE (
                 (NOT cmhead.cmhead_posted)
               AND (NOT cmhead.cmhead_hold)
           )
     )
 UNIONSELECT cmhead.cmhead_id AS orderid
     , (-1) AS itemid
     ,'' AS documentnumber
     ,'' AS cust_number
     ,'' AS billtoname
     , cmhead.cmhead_number AS ordernumber
     , (-1) AS linenumber
     ,'Sales Tax' AS item
     , tax.tax_descrip AS itemdescrip
     ,'' AS iteminvuom
     ,'' AS qtytobill
     , formatmoney
     (
           (cmitemtax.taxhist_tax * 
                 (-1.0)
           )
     ) AS price
     , formatmoney
     (
           (cmitemtax.taxhist_tax * 
                 (-1.0)
           )
     ) AS extprice
     ,'Debit' AS sence
     , CASE WHEN 
     (accnt.accnt_id IS NULL) THEN 'Not Assigned'::text ELSE 
     (
           (formatglaccountlong
                 (accnt.accnt_id) || ' - '::text
           ) || accnt.accnt_descrip
     ) END AS account 
  FROM (
           (
                 (
                       (cmhead 
                          JOIN cmitem 
                            ON (
                                   (cmitem.cmitem_cmhead_id = cmhead.cmhead_id)
                             )
                       )
                    JOIN cmitemtax 
                      ON (
                             (cmitemtax.taxhist_parent_id = cmitem.cmitem_id)
                       )
                 )
              JOIN tax 
                ON (
                       (tax.tax_id = cmitemtax.taxhist_tax_id)
                 )
           )
   LEFT JOIN accnt 
          ON (
                 (accnt.accnt_id = tax.tax_sales_accnt_id)
           )
     )
 WHERE (
           (NOT cmhead.cmhead_posted)
         AND (NOT cmhead.cmhead_hold)
     )
)
UNIONSELECT cmhead.cmhead_id AS orderid
, cmitem.cmitem_id AS itemid
,'' AS documentnumber
,'' AS cust_number
,'' AS billtoname
, cmhead.cmhead_number AS ordernumber
, cmitem.cmitem_linenumber AS linenumber
, item.item_number AS item
, item.item_descrip1 AS itemdescrip
, uom.uom_name AS iteminvuom
, formatqty
(COALESCE
     (
           (cmitem.cmitem_qtycredit * cmitem.cmitem_qty_invuomratio)
           , (0)::numeric
     )
) AS qtytobill
, formatprice
(COALESCE
     (
           (cmitem.cmitem_unitprice / cmitem.cmitem_price_invuomratio)
           , (0)::numeric
     )
) AS price
, formatmoney
(COALESCE
     (round
           (
                 (
                       (cmitem.cmitem_qtycredit * cmitem.cmitem_qty_invuomratio) * 
                       (cmitem.cmitem_unitprice / cmitem.cmitem_price_invuomratio)
                 )
                 , 2
           )
           , (0)::numeric
     )
) AS extprice
,'Debit' AS sence
, COALESCE
(
     (
      SELECT formatglaccountlong
           (accnt.accnt_id) AS formatglaccountlong 
        FROM accnt
           , salesaccnt 
       WHERE (
                 (salesaccnt.salesaccnt_sales_accnt_id = accnt.accnt_id)
               AND (salesaccnt.salesaccnt_id = findsalesaccnt
                       (cmitem.cmitem_itemsite_id
                             ,'IS'::text
                             , cmhead.cmhead_cust_id
                             , cmhead.cmhead_saletype_id
                             , cmhead.cmhead_shipzone_id
                       )
                 )
           )
     )
     ,'Not Assigned'::text
) AS account 
FROM item
, itemsite
, cmhead
, cmitem
, uom 
WHERE (
     (
           (
                 (
                       (
                             (cmitem.cmitem_cmhead_id = cmhead.cmhead_id)
                           AND (cmitem.cmitem_itemsite_id = itemsite.itemsite_id)
                       )
                     AND (itemsite.itemsite_item_id = item.item_id)
                 )
               AND (item.item_inv_uom_id = uom.uom_id)
           )
         AND (NOT cmhead.cmhead_posted)
     )
   AND (NOT cmhead.cmhead_hold)
)
ORDER BY 6
, 7;

Index - Schema public


View: public.creditmemoitem

Single point for credit memo item (cmitem) calculations.

public.creditmemoitem Structure
F-Key Name Type Description
cmitem_id integer
cmitem_cmhead_id integer
cmitem_linenumber integer
cmitem_itemsite_id integer
cmitem_qtycredit numeric(18,6)
cmitem_qtyreturned numeric(18,6)
cmitem_unitprice numeric(16,4)
cmitem_comments text
cmitem_rsncode_id integer
cmitem_taxtype_id integer
cmitem_qty_uom_id integer
cmitem_qty_invuomratio numeric(20,10)
cmitem_price_uom_id integer
cmitem_price_invuomratio numeric(20,10)
cmitem_raitem_id integer
cmitem_updateinv boolean
item_id integer
qty numeric
unitprice numeric
extprice numeric
baseextprice numeric
tax numeric
unitcost numeric
SELECT cmitem.cmitem_id
, cmitem.cmitem_cmhead_id
, cmitem.cmitem_linenumber
, cmitem.cmitem_itemsite_id
, cmitem.cmitem_qtycredit
, cmitem.cmitem_qtyreturned
, cmitem.cmitem_unitprice
, cmitem.cmitem_comments
, cmitem.cmitem_rsncode_id
, cmitem.cmitem_taxtype_id
, cmitem.cmitem_qty_uom_id
, cmitem.cmitem_qty_invuomratio
, cmitem.cmitem_price_uom_id
, cmitem.cmitem_price_invuomratio
, cmitem.cmitem_raitem_id
, cmitem.cmitem_updateinv
, itemsite.itemsite_item_id AS item_id
, COALESCE
(
     (cmitem.cmitem_qtycredit * cmitem.cmitem_qty_invuomratio)
     , (0)::numeric
) AS qty
, COALESCE
(
     (cmitem.cmitem_unitprice / cmitem.cmitem_price_invuomratio)
     , (0)::numeric
) AS unitprice
, COALESCE
(round
     (
           (
                 (cmitem.cmitem_qtycredit * cmitem.cmitem_qty_invuomratio) * 
                 (cmitem.cmitem_unitprice / cmitem.cmitem_price_invuomratio)
           )
           , 2
     )
     , (0)::numeric
) AS extprice
, currtobase
(cmhead.cmhead_curr_id
     , COALESCE
     (round
           (
                 (
                       (cmitem.cmitem_qtycredit * cmitem.cmitem_qty_invuomratio) * 
                       (cmitem.cmitem_unitprice / cmitem.cmitem_price_invuomratio)
                 )
                 , 2
           )
           , (0)::numeric
     )
     , cmhead.cmhead_docdate
) AS baseextprice
, (
SELECT COALESCE
     (sum
           (cmitemtax.taxhist_tax)
           , (0)::numeric
     ) AS "coalesce"
  FROM cmitemtax 
 WHERE (cmitemtax.taxhist_parent_id = cmitem.cmitem_id)
) AS tax
, CASE WHEN 
(itemsite.itemsite_costmethod = 'A'::bpchar) THEN avgcost
(itemsite.itemsite_id) ELSE stdcost
(itemsite.itemsite_item_id) END AS unitcost 
FROM (
     (cmitem 
        JOIN cmhead 
          ON (
                 (cmhead.cmhead_id = cmitem.cmitem_cmhead_id)
           )
     )
LEFT JOIN itemsite 
    ON (
           (itemsite.itemsite_id = cmitem.cmitem_itemsite_id)
     )
);

Index - Schema public


Table: public.crmacct

CRM Accounts are umbrella records that tie together people and organizations with whom we have business relationships.

public.crmacct Structure
F-Key Name Type Description
crmacct_id serial PRIMARY KEY

Internal ID of this CRM Account.
crmacct_number text UNIQUE NOT NULL

Abbreviated human-readable identifier for this CRM Account.
crmacct_name text

Long name of this CRM Account.
crmacct_active boolean DEFAULT true

This CRM Account is available for new activity.
crmacct_type character(1)

This indicates whether the CRM Account represents an organization or an individual person.
public.custinfo.cust_id crmacct_cust_id integer

If this is not null, this CRM Account is a Customer.
crmacct_competitor_id integer

For now, > 0 indicates this CRM Account is a competitor. Eventually this may become a foreign key to a table of competitors.
crmacct_partner_id integer

For now, > 0 indicates this CRM Account is a partner. Eventually this may become a foreign key to a table of partners.
public.prospect.prospect_id crmacct_prospect_id integer

If this is not null, this CRM Account is a Prospect.
public.vendinfo.vend_id crmacct_vend_id integer

If this is not null, this CRM Account is a Vendor.
public.cntct.cntct_id crmacct_cntct_id_1 integer

The primary contact for the CRM Account.
public.cntct.cntct_id crmacct_cntct_id_2 integer

The secondary contact for the CRM Account.
public.crmacct.crmacct_id crmacct_parent_id integer

The internal ID of an (optional) parent CRM Account. For example, if the current CRM Account is a subsidiary of another company, the crmacct_parent_id points to the CRM Account representing that parent company.
crmacct_notes text

Free-form comments pertaining to the CRM Account.
public.taxauth.taxauth_id crmacct_taxauth_id integer

If this is not null, this CRM Account is a Tax Authority.
crmacct_owner_username text

The application User responsible for this CRM Account.
public.emp.emp_id crmacct_emp_id integer

If this is not null, this CRM Account is an Employee.
public.salesrep.salesrep_id crmacct_salesrep_id integer

If this is not null, this CRM Account is a Sales Rep.
crmacct_usr_username text

If this is not null, this CRM Account is an application User.

 

public.crmacct Constraints
Name Constraint
crmacct_crmacct_number_check CHECK ((crmacct_number <> ''::text))
crmacct_crmacct_type_check CHECK ((crmacct_type = ANY (ARRAY['I'::bpchar, 'O'::bpchar])))
crmacct_crmacct_usr_username_check CHECK ((btrim(crmacct_usr_username) <> ''::text))
crmacct_owner_username_check CHECK ((btrim(crmacct_owner_username) <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.crmacctsel

This table records the proposed conditions of a CRM Account merge. When this merge is performed, the BOOLEAN columns in this table indicate which values in the crmacct table will be copied to the target record. Data in this table are temporary and will be removed by a purge.

public.crmacctsel Structure
F-Key Name Type Description
public.crmacct.crmacct_id crmacctsel_src_crmacct_id integer PRIMARY KEY

This is the internal ID of the CRM Account record the data will come from during the merge.
public.crmacct.crmacct_id crmacctsel_dest_crmacct_id integer

This is the internal ID of the CRM Account record the data will go to during the merge. If crmacctsel_src_crmacct_id = crmacctsel_dest_crmacct_id, they indicate which crmacct record is the destination of the merge, meaning this is the record that will remain in the database after the merge has been completed and the intermediate data have been purged.
crmacctsel_mrg_crmacct_active boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_cntct_id_1 boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_cntct_id_2 boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_competitor_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_cust_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_emp_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_name boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_notes boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_owner_username boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_parent_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_partner_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_prospect_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_salesrep_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_taxauth_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_type boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_usr_username boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_vend_id boolean NOT NULL DEFAULT false
crmacctsel_mrg_crmacct_number boolean NOT NULL DEFAULT false

Index - Schema public


Table: public.curr_rate

Exchange Rates Between Base and Foreign Currencies

public.curr_rate Structure
F-Key Name Type Description
curr_rate_id serial PRIMARY KEY
public.curr_symbol.curr_id curr_id integer UNIQUE#1 NOT NULL
curr_rate numeric(16,8) NOT NULL
curr_effective date UNIQUE#1 NOT NULL
curr_expires date NOT NULL

 

public.curr_rate Constraints
Name Constraint
curr_rate_curr_rate_check CHECK ((curr_rate > (0)::numeric))

Index - Schema public


Table: public.curr_symbol

Currency Names, Symbols, and Abbreviations

public.curr_symbol Structure
F-Key Name Type Description
curr_id serial PRIMARY KEY
curr_base boolean NOT NULL DEFAULT false
curr_name character varying(50) UNIQUE NOT NULL
curr_symbol character varying(9) NOT NULL
curr_abbr character varying(3) UNIQUE NOT NULL

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.custform

Customer Form assignment information

public.custform Structure
F-Key Name Type Description
custform_id integer PRIMARY KEY DEFAULT nextval(('"custform_custform_id_seq"'::text)::regclass)
custform_custtype_id integer
custform_custtype text
custform_invoice_report_id integer

Obsolete -- reference custform_invoice_report_name instead.
custform_creditmemo_report_id integer

Obsolete -- reference custform_creditmemo_report_name instead.
custform_quote_report_id integer

Obsolete -- reference custform_quote_report_name instead.
custform_packinglist_report_id integer

Obsolete -- reference custform_packinglist_report_name instead.
custform_statement_report_id integer

Obsolete -- reference custform_statement_report_name instead.
custform_sopicklist_report_id integer

Obsolete -- reference custform_sopicklist_report_name instead.
custform_invoice_report_name text
custform_creditmemo_report_name text
custform_quote_report_name text
custform_packinglist_report_name text
custform_statement_report_name text
custform_sopicklist_report_name text

Index - Schema public


Table: public.custgrp

Customer Group information

public.custgrp Structure
F-Key Name Type Description
custgrp_id integer PRIMARY KEY DEFAULT nextval(('"custgrp_custgrp_id_seq"'::text)::regclass)
custgrp_name text NOT NULL
custgrp_descrip text

 

public.custgrp Constraints
Name Constraint
custgrp_custgrp_name_check CHECK ((custgrp_name <> ''::text))

Index - Schema public


Table: public.custgrpitem

Customer Group Item information

public.custgrpitem Structure
F-Key Name Type Description
custgrpitem_id integer PRIMARY KEY DEFAULT nextval(('"custgrpitem_custgrpitem_id_seq"'::text)::regclass)
custgrpitem_custgrp_id integer
custgrpitem_cust_id integer

Index - Schema public


Table: public.custinfo

Customer information

public.custinfo Structure
F-Key Name Type Description
cust_id integer PRIMARY KEY DEFAULT nextval(('cust_cust_id_seq'::text)::regclass)
cust_active boolean NOT NULL
public.custtype.custtype_id cust_custtype_id integer
public.salesrep.salesrep_id cust_salesrep_id integer
cust_commprcnt numeric(10,6)
cust_name text
cust_creditlmt integer
cust_creditrating text
cust_financecharge boolean
cust_backorder boolean NOT NULL
cust_partialship boolean NOT NULL
public.terms.terms_id cust_terms_id integer
cust_discntprcnt numeric(10,6) NOT NULL
cust_balmethod character(1) NOT NULL
cust_ffshipto boolean NOT NULL
public.shipform.shipform_id cust_shipform_id integer
cust_shipvia text
cust_blanketpos boolean NOT NULL
cust_shipchrg_id integer NOT NULL
cust_creditstatus character(1) NOT NULL
cust_comments text
cust_ffbillto boolean NOT NULL
cust_usespos boolean NOT NULL
cust_number text UNIQUE NOT NULL
cust_dateadded date DEFAULT ('now'::text)::date
cust_exported boolean DEFAULT false
cust_emaildelivery boolean DEFAULT false
cust_ediemail text

Deprecated column - DO NOT USE
cust_edisubject text

Deprecated column - DO NOT USE
cust_edifilename text

Deprecated column - DO NOT USE
cust_ediemailbody text

Deprecated column - DO NOT USE
cust_autoupdatestatus boolean NOT NULL
cust_autoholdorders boolean NOT NULL
cust_edicc text

Deprecated column - DO NOT USE
cust_ediprofile_id integer

Deprecated column - DO NOT USE
cust_preferred_warehous_id integer NOT NULL DEFAULT (-1)
public.curr_symbol.curr_id cust_curr_id integer DEFAULT basecurrid()
public.curr_symbol.curr_id cust_creditlmt_curr_id integer DEFAULT basecurrid()
public.cntct.cntct_id cust_cntct_id integer
public.cntct.cntct_id cust_corrcntct_id integer
cust_soemaildelivery boolean DEFAULT false
cust_soediemail text

Deprecated column - DO NOT USE
cust_soedisubject text

Deprecated column - DO NOT USE
cust_soedifilename text

Deprecated column - DO NOT USE
cust_soediemailbody text

Deprecated column - DO NOT USE
cust_soedicc text

Deprecated column - DO NOT USE
cust_soediprofile_id integer

Deprecated column - DO NOT USE
cust_gracedays integer
cust_ediemailhtml boolean NOT NULL DEFAULT false

Deprecated column - DO NOT USE
cust_soediemailhtml boolean NOT NULL DEFAULT false

Deprecated column - DO NOT USE
public.taxzone.taxzone_id cust_taxzone_id integer

 

public.custinfo Constraints
Name Constraint
custinfo_balmethod_check CHECK (((cust_balmethod = 'B'::bpchar) OR (cust_balmethod = 'O'::bpchar)))
custinfo_creditstatus_check CHECK ((((cust_creditstatus = 'G'::bpchar) OR (cust_creditstatus = 'W'::bpchar)) OR (cust_creditstatus = 'H'::bpchar)))
custinfo_cust_number_check CHECK ((cust_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.custtype

Customer Type information

public.custtype Structure
F-Key Name Type Description
custtype_id integer PRIMARY KEY DEFAULT nextval(('custtype_custtype_id_seq'::text)::regclass)
custtype_code text UNIQUE NOT NULL
custtype_descrip text NOT NULL
custtype_char boolean NOT NULL DEFAULT false

 

public.custtype Constraints
Name Constraint
custtype_custtype_code_check CHECK ((custtype_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.dept

List of Departments

public.dept Structure
F-Key Name Type Description
dept_id serial PRIMARY KEY
dept_number text UNIQUE NOT NULL
dept_name text NOT NULL

 

public.dept Constraints
Name Constraint
dept_dept_number_check CHECK ((dept_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.destination

Destination information

public.destination Structure
F-Key Name Type Description
destination_id integer PRIMARY KEY DEFAULT nextval(('"destination_destination_id_seq"'::text)::regclass)
destination_name text
destination_city text
destination_state text
destination_comments text

Index - Schema public


Table: public.docass

Document Assignement References

public.docass Structure
F-Key Name Type Description
docass_id serial PRIMARY KEY
docass_source_id integer NOT NULL
docass_source_type text NOT NULL
docass_target_id integer NOT NULL
docass_target_type text NOT NULL DEFAULT 'URL'::text
docass_purpose character(1) NOT NULL DEFAULT 'S'::bpchar

 

public.docass Constraints
Name Constraint
docass_docass_purpose_check CHECK (((((((((docass_purpose = 'I'::bpchar) OR (docass_purpose = 'E'::bpchar)) OR (docass_purpose = 'M'::bpchar)) OR (docass_purpose = 'P'::bpchar)) OR (docass_purpose = 'A'::bpchar)) OR (docass_purpose = 'C'::bpchar)) OR (docass_purpose = 'S'::bpchar)) OR (docass_purpose = 'D'::bpchar)))

Index - Schema public


View: public.docinfo

public.docinfo Structure
F-Key Name Type Description
id integer
target_number text
target_type text
target_id integer
source_type text
source_id integer
name text
description text
purpose bpchar
(
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (
                                                     (
                                                           (
                                                                 (
                                                                       (
                                                                             (
                                                                                   (
                                                                                         (
                                                                                               (
                                                                                                     (
                                                                                                           (
                                                                                                                 (
                                                                                                                       (
                                                                                                                             (
                                                                                                                                   (
                                                                                                                                         (
                                                                                                                                               (
                                                                                                                                                     (
                                                                                                                                                           (
                                                                                                                                                                 (
                                                                                                                                                                       (
                                                                                                                                                                        SELECT imageass.imageass_id AS id
                                                                                                                                                                             , (image.image_id)::text AS target_number
                                                                                                                                                                             ,'IMG' AS target_type
                                                                                                                                                                             , imageass.imageass_image_id AS target_id
                                                                                                                                                                             , imageass.imageass_source AS source_type
                                                                                                                                                                             , imageass.imageass_source_id AS source_id
                                                                                                                                                                             , image.image_name AS name
                                                                                                                                                                             , image.image_descrip AS description
                                                                                                                                                                             , imageass.imageass_purpose AS purpose 
                                                                                                                                                                          FROM imageass
                                                                                                                                                                             , image 
                                                                                                                                                                         WHERE (imageass.imageass_image_id = image.image_id)
                                                                                                                                                                     UNION ALLSELECT url.url_id AS id
                                                                                                                                                                             , (url.url_id)::text AS target_number
                                                                                                                                                                             ,'URL' AS target_type
                                                                                                                                                                             , url.url_id AS target_id
                                                                                                                                                                             , url.url_source AS source_type
                                                                                                                                                                             , url.url_source_id AS source_id
                                                                                                                                                                             , url.url_title AS name
                                                                                                                                                                             , url.url_url AS description
                                                                                                                                                                             ,'S' AS purpose 
                                                                                                                                                                          FROM url 
                                                                                                                                                                         WHERE (url.url_stream IS NULL)
                                                                                                                                                                       )
                                                                                                                                                               UNION ALLSELECT url.url_id AS id
                                                                                                                                                                       , (url.url_id)::text AS target_number
                                                                                                                                                                       ,'FILE' AS target_type
                                                                                                                                                                       , url.url_id AS target_id
                                                                                                                                                                       , url.url_source AS source_type
                                                                                                                                                                       , url.url_source_id AS source_id
                                                                                                                                                                       , url.url_title AS name
                                                                                                                                                                       , url.url_url AS description
                                                                                                                                                                       ,'S' AS purpose 
                                                                                                                                                                    FROM url 
                                                                                                                                                                   WHERE (url.url_stream IS NOT NULL)
                                                                                                                                                                 )
                                                                                                                                                         UNION ALLSELECT docass.docass_id AS id
                                                                                                                                                                 , (incdt.incdt_number)::text AS target_number
                                                                                                                                                                 , docass.docass_target_type AS target_type
                                                                                                                                                                 , docass.docass_target_id AS target_id
                                                                                                                                                                 , docass.docass_source_type AS source_type
                                                                                                                                                                 , docass.docass_source_id AS source_id
                                                                                                                                                                 , incdt.incdt_summary AS name
                                                                                                                                                                 , firstline
                                                                                                                                                                 (incdt.incdt_descrip) AS description
                                                                                                                                                                 , docass.docass_purpose AS purpose 
                                                                                                                                                              FROM docass
                                                                                                                                                                 , incdt 
                                                                                                                                                             WHERE (
                                                                                                                                                                       (docass.docass_target_type = 'INCDT'::text)
                                                                                                                                                                     AND (docass.docass_target_id = incdt.incdt_id)
                                                                                                                                                                 )
                                                                                                                                                           )
                                                                                                                                                   UNION ALLSELECT docass.docass_id AS id
                                                                                                                                                           , (incdt.incdt_number)::text AS target_number
                                                                                                                                                           , docass.docass_source_type AS target_type
                                                                                                                                                           , docass.docass_source_id AS target_id
                                                                                                                                                           , docass.docass_target_type AS source_type
                                                                                                                                                           , docass.docass_target_id AS source_id
                                                                                                                                                           , incdt.incdt_summary AS name
                                                                                                                                                           , firstline
                                                                                                                                                           (incdt.incdt_descrip) AS description
                                                                                                                                                           , CASE WHEN 
                                                                                                                                                           (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                                                                                           (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                                                                                        FROM docass
                                                                                                                                                           , incdt 
                                                                                                                                                       WHERE (
                                                                                                                                                                 (docass.docass_source_type = 'INCDT'::text)
                                                                                                                                                               AND (docass.docass_source_id = incdt.incdt_id)
                                                                                                                                                           )
                                                                                                                                                     )
                                                                                                                                             UNION ALLSELECT docass.docass_id AS id
                                                                                                                                                     , (todoitem.todoitem_id)::text AS target_number
                                                                                                                                                     , docass.docass_target_type AS target_type
                                                                                                                                                     , docass.docass_target_id AS target_id
                                                                                                                                                     , docass.docass_source_type AS source_type
                                                                                                                                                     , docass.docass_source_id AS source_id
                                                                                                                                                     , todoitem.todoitem_name AS name
                                                                                                                                                     , firstline
                                                                                                                                                     (todoitem.todoitem_description) AS description
                                                                                                                                                     , docass.docass_purpose AS purpose 
                                                                                                                                                  FROM docass
                                                                                                                                                     , todoitem 
                                                                                                                                                 WHERE (
                                                                                                                                                           (docass.docass_target_type = 'TODO'::text)
                                                                                                                                                         AND (docass.docass_target_id = todoitem.todoitem_id)
                                                                                                                                                     )
                                                                                                                                               )
                                                                                                                                       UNION ALLSELECT docass.docass_id AS id
                                                                                                                                               , (todoitem.todoitem_id)::text AS target_number
                                                                                                                                               , docass.docass_source_type AS target_type
                                                                                                                                               , docass.docass_source_id AS target_id
                                                                                                                                               , docass.docass_target_type AS source_type
                                                                                                                                               , docass.docass_target_id AS source_id
                                                                                                                                               , todoitem.todoitem_name AS name
                                                                                                                                               , firstline
                                                                                                                                               (todoitem.todoitem_description) AS description
                                                                                                                                               , CASE WHEN 
                                                                                                                                               (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                                                                               (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                                                                            FROM docass
                                                                                                                                               , todoitem 
                                                                                                                                           WHERE (
                                                                                                                                                     (docass.docass_source_type = 'TODO'::text)
                                                                                                                                                   AND (docass.docass_source_id = todoitem.todoitem_id)
                                                                                                                                               )
                                                                                                                                         )
                                                                                                                                 UNION ALLSELECT docass.docass_id AS id
                                                                                                                                         , prj.prj_number AS target_number
                                                                                                                                         , docass.docass_target_type AS target_type
                                                                                                                                         , docass.docass_target_id AS target_id
                                                                                                                                         , docass.docass_source_type AS source_type
                                                                                                                                         , docass.docass_source_id AS source_id
                                                                                                                                         , prj.prj_name AS name
                                                                                                                                         , firstline
                                                                                                                                         (prj.prj_descrip) AS description
                                                                                                                                         , docass.docass_purpose AS purpose 
                                                                                                                                      FROM docass
                                                                                                                                         , prj 
                                                                                                                                     WHERE (
                                                                                                                                               (docass.docass_target_type = 'J'::text)
                                                                                                                                             AND (docass.docass_target_id = prj.prj_id)
                                                                                                                                         )
                                                                                                                                   )
                                                                                                                           UNION ALLSELECT docass.docass_id AS id
                                                                                                                                   , prj.prj_number AS target_number
                                                                                                                                   , docass.docass_source_type AS target_type
                                                                                                                                   , docass.docass_source_id AS target_id
                                                                                                                                   , docass.docass_target_type AS source_type
                                                                                                                                   , docass.docass_target_id AS source_id
                                                                                                                                   , prj.prj_name AS name
                                                                                                                                   , firstline
                                                                                                                                   (prj.prj_descrip) AS description
                                                                                                                                   , CASE WHEN 
                                                                                                                                   (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                                                                   (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                                                                FROM docass
                                                                                                                                   , prj 
                                                                                                                               WHERE (
                                                                                                                                         (docass.docass_source_type = 'J'::text)
                                                                                                                                       AND (docass.docass_source_id = prj.prj_id)
                                                                                                                                   )
                                                                                                                             )
                                                                                                                     UNION ALLSELECT docass.docass_id AS id
                                                                                                                             , item.item_number AS target_number
                                                                                                                             , docass.docass_target_type AS target_type
                                                                                                                             , docass.docass_target_id AS target_id
                                                                                                                             , docass.docass_source_type AS source_type
                                                                                                                             , docass.docass_source_id AS source_id
                                                                                                                             , firstline
                                                                                                                             (item.item_descrip1) AS name
                                                                                                                             , firstline
                                                                                                                             (item.item_descrip2) AS description
                                                                                                                             , docass.docass_purpose AS purpose 
                                                                                                                          FROM docass
                                                                                                                             , item 
                                                                                                                         WHERE (
                                                                                                                                   (docass.docass_target_type = 'I'::text)
                                                                                                                                 AND (docass.docass_target_id = item.item_id)
                                                                                                                             )
                                                                                                                       )
                                                                                                               UNION ALLSELECT docass.docass_id AS id
                                                                                                                       , item.item_number AS target_number
                                                                                                                       , docass.docass_source_type AS target_type
                                                                                                                       , docass.docass_source_id AS target_id
                                                                                                                       , docass.docass_target_type AS source_type
                                                                                                                       , docass.docass_target_id AS source_id
                                                                                                                       , firstline
                                                                                                                       (item.item_descrip1) AS name
                                                                                                                       , firstline
                                                                                                                       (item.item_descrip2) AS description
                                                                                                                       , CASE WHEN 
                                                                                                                       (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                                                       (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                                                    FROM docass
                                                                                                                       , item 
                                                                                                                   WHERE (
                                                                                                                             (docass.docass_source_type = 'I'::text)
                                                                                                                           AND (docass.docass_source_id = item.item_id)
                                                                                                                       )
                                                                                                                 )
                                                                                                         UNION ALLSELECT docass.docass_id AS id
                                                                                                                 , crmacct.crmacct_number AS target_number
                                                                                                                 , docass.docass_target_type AS target_type
                                                                                                                 , docass.docass_target_id AS target_id
                                                                                                                 , docass.docass_source_type AS source_type
                                                                                                                 , docass.docass_source_id AS source_id
                                                                                                                 , crmacct.crmacct_name AS name
                                                                                                                 , firstline
                                                                                                                 (crmacct.crmacct_notes) AS description
                                                                                                                 , docass.docass_purpose AS purpose 
                                                                                                              FROM docass
                                                                                                                 , crmacct 
                                                                                                             WHERE (
                                                                                                                       (docass.docass_target_type = 'CRMA'::text)
                                                                                                                     AND (docass.docass_target_id = crmacct.crmacct_id)
                                                                                                                 )
                                                                                                           )
                                                                                                   UNION ALLSELECT docass.docass_id AS id
                                                                                                           , crmacct.crmacct_number AS target_number
                                                                                                           , docass.docass_source_type AS target_type
                                                                                                           , docass.docass_source_id AS target_id
                                                                                                           , docass.docass_target_type AS source_type
                                                                                                           , docass.docass_target_id AS source_id
                                                                                                           , crmacct.crmacct_name AS name
                                                                                                           , firstline
                                                                                                           (crmacct.crmacct_notes) AS description
                                                                                                           , CASE WHEN 
                                                                                                           (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                                           (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                                        FROM docass
                                                                                                           , crmacct 
                                                                                                       WHERE (
                                                                                                                 (docass.docass_source_type = 'CRMA'::text)
                                                                                                               AND (docass.docass_source_id = crmacct.crmacct_id)
                                                                                                           )
                                                                                                     )
                                                                                                 UNIONSELECT docass.docass_id AS id
                                                                                                     , custinfo.cust_number AS target_number
                                                                                                     , docass.docass_target_type AS target_type
                                                                                                     , docass.docass_target_id AS target_id
                                                                                                     , docass.docass_source_type AS source_type
                                                                                                     , docass.docass_source_id AS source_id
                                                                                                     , custinfo.cust_name AS name
                                                                                                     , firstline
                                                                                                     (custinfo.cust_comments) AS description
                                                                                                     , docass.docass_purpose AS purpose 
                                                                                                  FROM docass
                                                                                                     , custinfo 
                                                                                                 WHERE (
                                                                                                           (docass.docass_target_type = 'C'::text)
                                                                                                         AND (docass.docass_target_id = custinfo.cust_id)
                                                                                                     )
                                                                                               )
                                                                                       UNION ALLSELECT docass.docass_id AS id
                                                                                               , custinfo.cust_number AS target_number
                                                                                               , docass.docass_source_type AS target_type
                                                                                               , docass.docass_source_id AS target_id
                                                                                               , docass.docass_target_type AS source_type
                                                                                               , docass.docass_target_id AS source_id
                                                                                               , custinfo.cust_name AS name
                                                                                               , firstline
                                                                                               (custinfo.cust_comments) AS description
                                                                                               , CASE WHEN 
                                                                                               (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                               (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                            FROM docass
                                                                                               , custinfo 
                                                                                           WHERE (
                                                                                                     (docass.docass_source_type = 'C'::text)
                                                                                                   AND (docass.docass_source_id = custinfo.cust_id)
                                                                                               )
                                                                                         )
                                                                                 UNION ALLSELECT docass.docass_id AS id
                                                                                         , vendinfo.vend_number AS target_number
                                                                                         , docass.docass_target_type AS target_type
                                                                                         , docass.docass_target_id AS target_id
                                                                                         , docass.docass_source_type AS source_type
                                                                                         , docass.docass_source_id AS source_id
                                                                                         , vendinfo.vend_name AS name
                                                                                         , firstline
                                                                                         (vendinfo.vend_comments) AS description
                                                                                         , docass.docass_purpose AS purpose 
                                                                                      FROM docass
                                                                                         , vendinfo 
                                                                                     WHERE (
                                                                                               (docass.docass_target_type = 'V'::text)
                                                                                             AND (docass.docass_target_id = vendinfo.vend_id)
                                                                                         )
                                                                                   )
                                                                           UNION ALLSELECT docass.docass_id AS id
                                                                                   , vendinfo.vend_number AS target_number
                                                                                   , docass.docass_source_type AS target_type
                                                                                   , docass.docass_source_id AS target_id
                                                                                   , docass.docass_target_type AS source_type
                                                                                   , docass.docass_target_id AS source_id
                                                                                   , vendinfo.vend_name AS name
                                                                                   , firstline
                                                                                   (vendinfo.vend_comments) AS description
                                                                                   , CASE WHEN 
                                                                                   (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                                   (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                                FROM docass
                                                                                   , vendinfo 
                                                                               WHERE (
                                                                                         (docass.docass_source_type = 'V'::text)
                                                                                       AND (docass.docass_source_id = vendinfo.vend_id)
                                                                                   )
                                                                             )
                                                                     UNION ALLSELECT docass.docass_id AS id
                                                                             , cntct.cntct_number AS target_number
                                                                             , docass.docass_target_type AS target_type
                                                                             , docass.docass_target_id AS target_id
                                                                             , docass.docass_source_type AS source_type
                                                                             , docass.docass_source_id AS source_id
                                                                             , cntct.cntct_name AS name
                                                                             , cntct.cntct_title AS description
                                                                             , docass.docass_purpose AS purpose 
                                                                          FROM docass
                                                                             , cntct 
                                                                         WHERE (
                                                                                   (docass.docass_target_type = 'T'::text)
                                                                                 AND (docass.docass_target_id = cntct.cntct_id)
                                                                             )
                                                                       )
                                                               UNION ALLSELECT docass.docass_id AS id
                                                                       , cntct.cntct_number AS target_number
                                                                       , docass.docass_source_type AS target_type
                                                                       , docass.docass_source_id AS target_id
                                                                       , docass.docass_target_type AS source_type
                                                                       , docass.docass_target_id AS source_id
                                                                       , cntct.cntct_name AS name
                                                                       , cntct.cntct_title AS description
                                                                       , CASE WHEN 
                                                                       (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                                       (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                                    FROM docass
                                                                       , cntct 
                                                                   WHERE (
                                                                             (docass.docass_source_type = 'T'::text)
                                                                           AND (docass.docass_source_id = cntct.cntct_id)
                                                                       )
                                                                 )
                                                         UNION ALLSELECT docass.docass_id AS id
                                                                 , (ophead.ophead_id)::text AS target_number
                                                                 , docass.docass_target_type AS target_type
                                                                 , docass.docass_target_id AS target_id
                                                                 , docass.docass_source_type AS source_type
                                                                 , docass.docass_source_id AS source_id
                                                                 , ophead.ophead_name AS name
                                                                 , firstline
                                                                 (ophead.ophead_notes) AS description
                                                                 , docass.docass_purpose AS purpose 
                                                              FROM docass
                                                                 , ophead 
                                                             WHERE (
                                                                       (docass.docass_target_type = 'OPP'::text)
                                                                     AND (docass.docass_target_id = ophead.ophead_id)
                                                                 )
                                                           )
                                                   UNION ALLSELECT docass.docass_id AS id
                                                           , (ophead.ophead_id)::text AS target_number
                                                           , docass.docass_source_type AS target_type
                                                           , docass.docass_source_id AS target_id
                                                           , docass.docass_target_type AS source_type
                                                           , docass.docass_target_id AS source_id
                                                           , ophead.ophead_name AS name
                                                           , firstline
                                                           (ophead.ophead_notes) AS description
                                                           , CASE WHEN 
                                                           (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                                           (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                                        FROM docass
                                                           , ophead 
                                                       WHERE (
                                                                 (docass.docass_source_type = 'OPP'::text)
                                                               AND (docass.docass_source_id = ophead.ophead_id)
                                                           )
                                                     )
                                             UNION ALLSELECT docass.docass_id AS id
                                                     , quhead.quhead_number AS target_number
                                                     , docass.docass_target_type AS target_type
                                                     , docass.docass_target_id AS target_id
                                                     , docass.docass_source_type AS source_type
                                                     , docass.docass_source_id AS source_id
                                                     , custinfo.cust_name AS name
                                                     , firstline
                                                     (quhead.quhead_ordercomments) AS description
                                                     , docass.docass_purpose AS purpose 
                                                  FROM docass
                                                     , quhead
                                                     , custinfo 
                                                 WHERE (
                                                           (
                                                                 (docass.docass_target_type = 'Q'::text)
                                                               AND (docass.docass_target_id = quhead.quhead_id)
                                                           )
                                                         AND (custinfo.cust_id = quhead.quhead_cust_id)
                                                     )
                                               )
                                       UNION ALLSELECT docass.docass_id AS id
                                               , quhead.quhead_number AS target_number
                                               , docass.docass_source_type AS target_type
                                               , docass.docass_source_id AS target_id
                                               , docass.docass_target_type AS source_type
                                               , docass.docass_target_id AS source_id
                                               , custinfo.cust_name AS name
                                               , firstline
                                               (quhead.quhead_ordercomments) AS description
                                               , CASE WHEN 
                                               (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                               (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                            FROM docass
                                               , quhead
                                               , custinfo 
                                           WHERE (
                                                     (
                                                           (docass.docass_source_type = 'Q'::text)
                                                         AND (docass.docass_source_id = quhead.quhead_id)
                                                     )
                                                   AND (custinfo.cust_id = quhead.quhead_cust_id)
                                               )
                                         )
                                 UNION ALLSELECT docass.docass_id AS id
                                         , cohead.cohead_number AS target_number
                                         , docass.docass_target_type AS target_type
                                         , docass.docass_target_id AS target_id
                                         , docass.docass_source_type AS source_type
                                         , docass.docass_source_id AS source_id
                                         , custinfo.cust_name AS name
                                         , firstline
                                         (cohead.cohead_ordercomments) AS description
                                         , docass.docass_purpose AS purpose 
                                      FROM docass
                                         , cohead
                                         , custinfo 
                                     WHERE (
                                               (
                                                     (docass.docass_target_type = 'S'::text)
                                                   AND (docass.docass_target_id = cohead.cohead_id)
                                               )
                                             AND (custinfo.cust_id = cohead.cohead_cust_id)
                                         )
                                   )
                           UNION ALLSELECT docass.docass_id AS id
                                   , cohead.cohead_number AS target_number
                                   , docass.docass_source_type AS target_type
                                   , docass.docass_source_id AS target_id
                                   , docass.docass_target_type AS source_type
                                   , docass.docass_target_id AS source_id
                                   , custinfo.cust_name AS name
                                   , firstline
                                   (cohead.cohead_ordercomments) AS description
                                   , CASE WHEN 
                                   (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                                   (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                                FROM docass
                                   , cohead
                                   , custinfo 
                               WHERE (
                                         (
                                               (docass.docass_source_type = 'S'::text)
                                             AND (docass.docass_source_id = cohead.cohead_id)
                                         )
                                       AND (custinfo.cust_id = cohead.cohead_cust_id)
                                   )
                             )
                     UNION ALLSELECT docass.docass_id AS id
                             , pohead.pohead_number AS target_number
                             , docass.docass_target_type AS target_type
                             , docass.docass_target_id AS target_id
                             , docass.docass_source_type AS source_type
                             , docass.docass_source_id AS source_id
                             , vendinfo.vend_name AS name
                             , firstline
                             (pohead.pohead_comments) AS description
                             , docass.docass_purpose AS purpose 
                          FROM docass
                             , pohead
                             , vendinfo 
                         WHERE (
                                   (
                                         (docass.docass_target_type = 'P'::text)
                                       AND (docass.docass_target_id = pohead.pohead_id)
                                   )
                                 AND (vendinfo.vend_id = pohead.pohead_vend_id)
                             )
                       )
               UNION ALLSELECT docass.docass_id AS id
                       , pohead.pohead_number AS target_number
                       , docass.docass_source_type AS target_type
                       , docass.docass_source_id AS target_id
                       , docass.docass_target_type AS source_type
                       , docass.docass_target_id AS source_id
                       , vendinfo.vend_name AS name
                       , firstline
                       (pohead.pohead_comments) AS description
                       , CASE WHEN 
                       (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
                       (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
                    FROM docass
                       , pohead
                       , vendinfo 
                   WHERE (
                             (
                                   (docass.docass_source_type = 'P'::text)
                                 AND (docass.docass_source_id = pohead.pohead_id)
                             )
                           AND (vendinfo.vend_id = pohead.pohead_vend_id)
                       )
                 )
         UNION ALLSELECT docass.docass_id AS id
                 , formatwonumber
                 (wo.wo_id) AS target_number
                 , docass.docass_target_type AS target_type
                 , docass.docass_target_id AS target_id
                 , docass.docass_source_type AS source_type
                 , docass.docass_source_id AS source_id
                 , item.item_descrip1 AS name
                 , item.item_descrip2 AS description
                 , docass.docass_purpose AS purpose 
              FROM docass
                 , wo
                 , itemsite
                 , item 
             WHERE (
                       (
                             (
                                   (docass.docass_target_type = 'W'::text)
                                 AND (docass.docass_target_id = wo.wo_id)
                             )
                           AND (wo.wo_itemsite_id = itemsite.itemsite_id)
                       )
                     AND (itemsite.itemsite_item_id = item.item_id)
                 )
           )
   UNION ALLSELECT docass.docass_id AS id
           , formatwonumber
           (wo.wo_id) AS target_number
           , docass.docass_source_type AS target_type
           , docass.docass_source_id AS target_id
           , docass.docass_target_type AS source_type
           , docass.docass_target_id AS source_id
           , item.item_descrip1 AS name
           , item.item_descrip2 AS description
           , CASE WHEN 
           (docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
           (docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
        FROM docass
           , wo
           , itemsite
           , item 
       WHERE (
                 (
                       (
                             (docass.docass_source_type = 'W'::text)
                           AND (docass.docass_source_id = wo.wo_id)
                       )
                     AND (wo.wo_itemsite_id = itemsite.itemsite_id)
                 )
               AND (itemsite.itemsite_item_id = item.item_id)
           )
     )
UNION ALLSELECT docass.docass_id AS id
     , emp.emp_number AS target_number
     , docass.docass_target_type AS target_type
     , docass.docass_target_id AS target_id
     , docass.docass_source_type AS source_type
     , docass.docass_source_id AS source_id
     , cntct.cntct_name AS name
     , cntct.cntct_title AS description
     , docass.docass_purpose AS purpose 
  FROM docass
     , (emp 
   LEFT JOIN cntct 
          ON (
                 (emp.emp_cntct_id = cntct.cntct_id)
           )
     )
 WHERE (
           (docass.docass_target_type = 'EMP'::text)
         AND (docass.docass_target_id = emp.emp_id)
     )
)
UNION ALLSELECT docass.docass_id AS id
, emp.emp_number AS target_number
, docass.docass_source_type AS target_type
, docass.docass_source_id AS target_id
, docass.docass_target_type AS source_type
, docass.docass_target_id AS source_id
, cntct.cntct_name AS name
, cntct.cntct_title AS description
, CASE WHEN 
(docass.docass_purpose = 'A'::bpchar) THEN 'C'::bpchar WHEN 
(docass.docass_purpose = 'C'::bpchar) THEN 'A'::bpchar ELSE docass.docass_purpose END AS purpose 
FROM docass
, (emp 
LEFT JOIN cntct 
    ON (
           (emp.emp_cntct_id = cntct.cntct_id)
     )
)
WHERE (
     (docass.docass_source_type = 'EMP'::text)
   AND (docass.docass_source_id = emp.emp_id)
);

Index - Schema public


Table: public.emp

Employee table describing the basic properties of an employee. Employees need not be system users.

public.emp Structure
F-Key Name Type Description
emp_id serial PRIMARY KEY
emp_code text UNIQUE NOT NULL

Short, human-readable name for employee. This value is kept synchronized with usr_username and salesrep_number, and so is unique across all three tables emp, usr, and salesrep.
emp_number text UNIQUE NOT NULL

Official employee number. This might be used for ID badges, payroll accounting, or other purposes.
emp_active boolean NOT NULL DEFAULT true
public.cntct.cntct_id emp_cntct_id integer
public.whsinfo.warehous_id emp_warehous_id integer
public.emp.emp_id emp_mgr_emp_id integer

Internal ID of this employee's manager/supervisor.
emp_wage_type text NOT NULL

The nature of the wage or employment agreement. 'H' indicates this employee is paid on an hourly basis (or some other period) while 'S' indicates this employee is salaried.
emp_wage numeric
public.curr_symbol.curr_id emp_wage_curr_id integer DEFAULT basecurrid()
emp_wage_period text NOT NULL

The periodicity of wage payment: 'H' for hourly, 'D' for daily, 'W' for weekly, 'BW' for biweekly, 'M' for monthly, 'Y' for yearly.
public.dept.dept_id emp_dept_id integer
public.shift.shift_id emp_shift_id integer
emp_notes text
public.image.image_id emp_image_id integer
emp_username text

DEPRECATED - the relationship between Employee and User is now maintained through the crmacct table.
emp_extrate numeric
emp_extrate_period text NOT NULL

The periodicity of external rate payment: 'H' for hourly, 'D' for daily, 'W' for weekly, 'BW' for biweekly, 'M' for monthly, 'Y' for yearly.
emp_startdate date DEFAULT ('now'::text)::date
emp_name text NOT NULL

 

public.emp Constraints
Name Constraint
emp_check CHECK (((((COALESCE(emp_wage_type, ''::text) = ''::text) OR (COALESCE(emp_wage_type, ''::text) = 'H'::text)) OR (COALESCE(emp_wage_type, ''::text) = 'S'::text)) AND ((COALESCE(emp_wage, (0)::numeric) = (0)::numeric) OR ((COALESCE(emp_wage_type, ''::text) <> ''::text) AND (emp_wage IS NOT NULL)))))
emp_emp_code_check CHECK ((emp_code <> ''::text))
emp_emp_number_check CHECK ((emp_number <> ''::text))
emp_emp_wage_period_check CHECK ((((((((COALESCE(emp_wage_period, ''::text) = ''::text) OR (COALESCE(emp_wage_period, ''::text) = 'H'::text)) OR (COALESCE(emp_wage_period, ''::text) = 'D'::text)) OR (COALESCE(emp_wage_period, ''::text) = 'W'::text)) OR (COALESCE(emp_wage_period, ''::text) = 'BW'::text)) OR (COALESCE(emp_wage_period, ''::text) = 'M'::text)) OR (COALESCE(emp_wage_period, ''::text) = 'Y'::text)))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.empgrp

public.empgrp Structure
F-Key Name Type Description
empgrp_id serial PRIMARY KEY
empgrp_name text UNIQUE NOT NULL
empgrp_descrip text NOT NULL

 

public.empgrp Constraints
Name Constraint
empgrp_empgrp_name_check CHECK ((empgrp_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.empgrpitem

public.empgrpitem Structure
F-Key Name Type Description
empgrpitem_id serial PRIMARY KEY
public.empgrp.empgrp_id empgrpitem_empgrp_id integer NOT NULL
public.emp.emp_id empgrpitem_emp_id integer NOT NULL

Index - Schema public


Table: public.evntlog

Event Notification history

public.evntlog Structure
F-Key Name Type Description
evntlog_id integer PRIMARY KEY DEFAULT nextval(('evntlog_evntlog_id_seq'::text)::regclass)
evntlog_evnttime timestamp with time zone
evntlog_evnttype_id integer
evntlog_ord_id integer
evntlog_dispatched timestamp with time zone
evntlog_action text
evntlog_warehous_id integer
evntlog_number text
evntlog_newvalue numeric(20,10)
evntlog_oldvalue numeric(20,10)
evntlog_newdate date
evntlog_olddate date
evntlog_ordtype character(2)
evntlog_username text
evntlog_dispatched_idx evntlog_dispatched evntlog_evntlog_username_idx evntlog_username

Index - Schema public


Table: public.evntnot

Temporary table for storing information about user Event Notification selections

public.evntnot Structure
F-Key Name Type Description
evntnot_id integer PRIMARY KEY DEFAULT nextval(('evntnot_evntnot_id_seq'::text)::regclass)
evntnot_evnttype_id integer
evntnot_warehous_id integer
evntnot_username text
evntnot_evnttype_id_idx evntnot_evnttype_id evntnot_warehous_id_idx evntnot_warehous_id

Index - Schema public


Table: public.evnttype

Event Type information

public.evnttype Structure
F-Key Name Type Description
evnttype_id integer PRIMARY KEY DEFAULT nextval(('evnttype_evnttype_id_seq'::text)::regclass)
evnttype_name text UNIQUE NOT NULL
evnttype_descrip text
evnttype_module text

 

public.evnttype Constraints
Name Constraint
evnttype_evnttype_name_check CHECK ((evnttype_name <> ''::text))

Index - Schema public


Table: public.expcat

Expense Category information

public.expcat Structure
F-Key Name Type Description
expcat_id serial PRIMARY KEY
expcat_code text UNIQUE NOT NULL
expcat_descrip text
expcat_exp_accnt_id integer
expcat_liability_accnt_id integer
expcat_active boolean
expcat_purchprice_accnt_id integer
expcat_freight_accnt_id integer

 

public.expcat Constraints
Name Constraint
expcat_expcat_code_check CHECK ((expcat_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.file

public.file Structure
F-Key Name Type Description
file_id serial PRIMARY KEY
file_title text NOT NULL
file_stream bytea
file_descrip text NOT NULL

Index - Schema public


Table: public.filter

public.filter Structure
F-Key Name Type Description
filter_id serial PRIMARY KEY
filter_screen text NOT NULL
filter_value text NOT NULL
filter_username text
filter_name text NOT NULL
filter_selected boolean DEFAULT false
filter_idx filter_screen, filter_username, filter_name

Index - Schema public


View: public.flaccnt

public.flaccnt Structure
F-Key Name Type Description
flhead_type character(1)
flitem_id integer
flitem_flhead_id integer
flitem_flgrp_id integer
flitem_order integer
flitem_accnt_id integer
flitem_showstart boolean
flitem_showend boolean
flitem_showdelta boolean
flitem_showbudget boolean
flitem_subtract boolean
flitem_showstartprcnt boolean
flitem_showendprcnt boolean
flitem_showdeltaprcnt boolean
flitem_showbudgetprcnt boolean
flitem_prcnt_flgrp_id integer
flitem_showdiff boolean
flitem_showdiffprcnt boolean
flitem_showcustom boolean
flitem_showcustomprcnt boolean
flitem_custom_source character(1)
flitem_company text
flitem_profit text
flitem_number text
flitem_sub text
flitem_type character(1)
flitem_subaccnttype_code text
accnt_id integer
accnt_type character(1)
accnt_company text
accnt_profit text
accnt_number text
accnt_sub text
prj_id integer
SELECT flhead.flhead_type
, flitem.flitem_id
, flitem.flitem_flhead_id
, flitem.flitem_flgrp_id
, flitem.flitem_order
, flitem.flitem_accnt_id
, flitem.flitem_showstart
, flitem.flitem_showend
, flitem.flitem_showdelta
, flitem.flitem_showbudget
, flitem.flitem_subtract
, flitem.flitem_showstartprcnt
, flitem.flitem_showendprcnt
, flitem.flitem_showdeltaprcnt
, flitem.flitem_showbudgetprcnt
, flitem.flitem_prcnt_flgrp_id
, flitem.flitem_showdiff
, flitem.flitem_showdiffprcnt
, flitem.flitem_showcustom
, flitem.flitem_showcustomprcnt
, flitem.flitem_custom_source
, flitem.flitem_company
, flitem.flitem_profit
, flitem.flitem_number
, flitem.flitem_sub
, flitem.flitem_type
, flitem.flitem_subaccnttype_code
, accnt.accnt_id
, accnt.accnt_type
, accnt.accnt_company
, accnt.accnt_profit
, accnt.accnt_number
, accnt.accnt_sub
, (-1) AS prj_id 
FROM (
     (flhead 
        JOIN flitem 
          ON (
                 (flhead.flhead_id = flitem.flitem_flhead_id)
           )
     )
  JOIN accnt 
    ON (
           (flitem.flitem_accnt_id = accnt.accnt_id)
     )
)
UNION ALLSELECT flhead.flhead_type
, flitem.flitem_id
, flitem.flitem_flhead_id
, flitem.flitem_flgrp_id
, flitem.flitem_order
, flitem.flitem_accnt_id
, flitem.flitem_showstart
, flitem.flitem_showend
, flitem.flitem_showdelta
, flitem.flitem_showbudget
, flitem.flitem_subtract
, flitem.flitem_showstartprcnt
, flitem.flitem_showendprcnt
, flitem.flitem_showdeltaprcnt
, flitem.flitem_showbudgetprcnt
, flitem.flitem_prcnt_flgrp_id
, flitem.flitem_showdiff
, flitem.flitem_showdiffprcnt
, flitem.flitem_showcustom
, flitem.flitem_showcustomprcnt
, flitem.flitem_custom_source
, flitem.flitem_company
, flitem.flitem_profit
, flitem.flitem_number
, flitem.flitem_sub
, flitem.flitem_type
, flitem.flitem_subaccnttype_code
, accnt.accnt_id
, accnt.accnt_type
, accnt.accnt_company
, accnt.accnt_profit
, accnt.accnt_number
, accnt.accnt_sub
, (-1) AS prj_id 
FROM (flhead 
  JOIN flitem 
    ON (
           (flhead.flhead_id = flitem.flitem_flhead_id)
     )
)
, accnt 
WHERE (
     (
           (
                 (
                       (
                             (
                                   (flitem.flitem_accnt_id = 
                                         (-1)
                                   )
                                 AND (
                                         (flitem.flitem_type = ''::bpchar)
                                        OR (accnt.accnt_type = flitem.flitem_type)
                                   )
                             )
                           AND (
                                   (flitem.flitem_company = 'All'::text)
                                  OR (accnt.accnt_company = flitem.flitem_company)
                             )
                       )
                     AND (
                             (flitem.flitem_profit = 'All'::text)
                            OR (accnt.accnt_profit = flitem.flitem_profit)
                       )
                 )
               AND (
                       (flitem.flitem_number = 'All'::text)
                      OR (accnt.accnt_number = flitem.flitem_number)
                 )
           )
         AND (
                 (flitem.flitem_sub = 'All'::text)
                OR (accnt.accnt_sub = flitem.flitem_sub)
           )
     )
   AND (
           (flitem.flitem_subaccnttype_code = 'All'::text)
          OR (accnt.accnt_subaccnttype_code = flitem.flitem_subaccnttype_code)
     )
)
ORDER BY 30
, 31
, 32
, 33;

Index - Schema public


Table: public.flcol

public.flcol Structure
F-Key Name Type Description
flcol_id serial PRIMARY KEY
flcol_flhead_id integer NOT NULL
flcol_name text
flcol_descrip text
flcol_report_id integer
flcol_month boolean
flcol_quarter boolean
flcol_year boolean
flcol_showdb boolean
flcol_prcnt boolean
flcol_priortype character(1)
flcol_priormonth boolean
flcol_priorquarter boolean
flcol_prioryear character(1)
flcol_priorprcnt boolean
flcol_priordiff boolean
flcol_priordiffprcnt boolean
flcol_budget boolean
flcol_budgetprcnt boolean
flcol_budgetdiff boolean
flcol_budgetdiffprcnt boolean

Index - Schema public


Table: public.flgrp

Financial Layout Group information

public.flgrp Structure
F-Key Name Type Description
flgrp_id serial PRIMARY KEY
flgrp_flhead_id integer
flgrp_flgrp_id integer
flgrp_order integer
flgrp_name text
flgrp_descrip text
flgrp_subtotal boolean NOT NULL DEFAULT false
flgrp_summarize boolean NOT NULL DEFAULT false
flgrp_subtract boolean NOT NULL DEFAULT false
flgrp_showstart boolean NOT NULL DEFAULT true
flgrp_showend boolean NOT NULL DEFAULT true
flgrp_showdelta boolean NOT NULL DEFAULT true
flgrp_showbudget boolean NOT NULL DEFAULT true
flgrp_showstartprcnt boolean NOT NULL DEFAULT false
flgrp_showendprcnt boolean NOT NULL DEFAULT false
flgrp_showdeltaprcnt boolean NOT NULL DEFAULT false
flgrp_showbudgetprcnt boolean NOT NULL DEFAULT false
flgrp_prcnt_flgrp_id integer NOT NULL DEFAULT (-1)
flgrp_showdiff boolean NOT NULL DEFAULT false
flgrp_showdiffprcnt boolean NOT NULL DEFAULT false
flgrp_showcustom boolean NOT NULL DEFAULT false
flgrp_showcustomprcnt boolean NOT NULL DEFAULT false
flgrp_usealtsubtotal boolean NOT NULL DEFAULT false
flgrp_altsubtotal text

Index - Schema public


Table: public.flhead

Financial Layout header information

public.flhead Structure
F-Key Name Type Description
flhead_id serial PRIMARY KEY
flhead_name text UNIQUE NOT NULL
flhead_descrip text
flhead_showtotal boolean NOT NULL DEFAULT false
flhead_showstart boolean NOT NULL DEFAULT true
flhead_showend boolean NOT NULL DEFAULT true
flhead_showdelta boolean NOT NULL DEFAULT true
flhead_showbudget boolean NOT NULL DEFAULT true
flhead_showdiff boolean NOT NULL DEFAULT false
flhead_showcustom boolean NOT NULL DEFAULT false
flhead_custom_label text
flhead_usealttotal boolean NOT NULL DEFAULT false
flhead_alttotal text
flhead_usealtbegin boolean NOT NULL DEFAULT false
flhead_altbegin text
flhead_usealtend boolean NOT NULL DEFAULT false
flhead_altend text
flhead_usealtdebits boolean NOT NULL DEFAULT false
flhead_altdebits text
flhead_usealtcredits boolean NOT NULL DEFAULT false
flhead_altcredits text
flhead_usealtbudget boolean NOT NULL DEFAULT false
flhead_altbudget text
flhead_usealtdiff boolean NOT NULL DEFAULT false
flhead_altdiff text
flhead_type character(1) NOT NULL DEFAULT 'A'::bpchar
flhead_active boolean NOT NULL DEFAULT true
flhead_sys boolean DEFAULT false
flhead_notes text DEFAULT ''::text

 

public.flhead Constraints
Name Constraint
flhead_flhead_name_check CHECK ((flhead_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.flitem

Financial Layout Account information

public.flitem Structure
F-Key Name Type Description
flitem_id serial PRIMARY KEY
flitem_flhead_id integer
flitem_flgrp_id integer
flitem_order integer
flitem_accnt_id integer
flitem_showstart boolean
flitem_showend boolean
flitem_showdelta boolean
flitem_showbudget boolean NOT NULL DEFAULT false
flitem_subtract boolean NOT NULL DEFAULT false
flitem_showstartprcnt boolean NOT NULL DEFAULT false
flitem_showendprcnt boolean NOT NULL DEFAULT false
flitem_showdeltaprcnt boolean NOT NULL DEFAULT false
flitem_showbudgetprcnt boolean NOT NULL DEFAULT false
flitem_prcnt_flgrp_id integer NOT NULL DEFAULT (-1)
flitem_showdiff boolean NOT NULL DEFAULT false
flitem_showdiffprcnt boolean NOT NULL DEFAULT false
flitem_showcustom boolean NOT NULL DEFAULT false
flitem_showcustomprcnt boolean NOT NULL DEFAULT false
flitem_custom_source character(1)
flitem_company text
flitem_profit text
flitem_number text
flitem_sub text
flitem_type character(1)
flitem_subaccnttype_code text

Index - Schema public


Table: public.flnotes

public.flnotes Structure
F-Key Name Type Description
flnotes_id serial NOT NULL
public.flhead.flhead_id flnotes_flhead_id integer UNIQUE#1
public.period.period_id flnotes_period_id integer UNIQUE#1
flnotes_notes text DEFAULT ''::text

Index - Schema public


Table: public.flrpt

Scratch table where financial reporting information is processed before being displayed.

public.flrpt Structure
F-Key Name Type Description
flrpt_flhead_id integer NOT NULL
flrpt_period_id integer NOT NULL
flrpt_username text NOT NULL
flrpt_order integer NOT NULL
flrpt_level integer NOT NULL
flrpt_type text NOT NULL
flrpt_type_id integer NOT NULL
flrpt_beginning numeric
flrpt_ending numeric
flrpt_debits numeric
flrpt_credits numeric
flrpt_budget numeric
flrpt_beginningprcnt numeric
flrpt_endingprcnt numeric
flrpt_debitsprcnt numeric
flrpt_creditsprcnt numeric
flrpt_budgetprcnt numeric
flrpt_parent_id integer
flrpt_diff numeric
flrpt_diffprcnt numeric
flrpt_custom numeric
flrpt_customprcnt numeric
flrpt_altname text
flrpt_accnt_id integer
flrpt_interval character(1)
flrpt_id serial PRIMARY KEY

Index - Schema public


Table: public.flspec

Financial Layout Special entries.

public.flspec Structure
F-Key Name Type Description
flspec_id serial PRIMARY KEY
flspec_flhead_id integer NOT NULL
flspec_flgrp_id integer NOT NULL
flspec_order integer NOT NULL
flspec_name text
flspec_type text
flspec_showstart boolean NOT NULL DEFAULT true
flspec_showend boolean NOT NULL DEFAULT true
flspec_showdelta boolean NOT NULL DEFAULT true
flspec_showbudget boolean NOT NULL DEFAULT false
flspec_subtract boolean NOT NULL DEFAULT false
flspec_showstartprcnt boolean NOT NULL DEFAULT false
flspec_showendprcnt boolean NOT NULL DEFAULT false
flspec_showdeltaprcnt boolean NOT NULL DEFAULT false
flspec_showbudgetprcnt boolean NOT NULL DEFAULT false
flspec_showdiff boolean NOT NULL DEFAULT false
flspec_showdiffprcnt boolean NOT NULL DEFAULT false
flspec_prcnt_flgrp_id integer NOT NULL DEFAULT (-1)
flspec_showcustom boolean NOT NULL DEFAULT false
flspec_showcustomprcnt boolean NOT NULL DEFAULT false
flspec_custom_source character(1)

Index - Schema public


Table: public.form

Form information

public.form Structure
F-Key Name Type Description
form_id integer PRIMARY KEY DEFAULT nextval(('"form_form_id_seq"'::text)::regclass)
form_name text UNIQUE NOT NULL
form_descrip text
form_report_id integer

Obsolete -- reference form_report_name instead.
form_key character varying(4)
form_report_name text

 

public.form Constraints
Name Constraint
form_form_name_check CHECK ((form_name <> ''::text))

Index - Schema public


Table: public.freightclass

This table is the freight price schedules.

public.freightclass Structure
F-Key Name Type Description
freightclass_id serial PRIMARY KEY
freightclass_code text UNIQUE NOT NULL
freightclass_descrip text

 

public.freightclass Constraints
Name Constraint
freightclass_freightclass_code_check CHECK ((freightclass_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.glseries

Temporary table for storing information about General Ledger (G/L) Series Entries before Series Entries are posted

public.glseries Structure
F-Key Name Type Description
glseries_id integer PRIMARY KEY DEFAULT nextval(('"glseries_glseries_id_seq"'::text)::regclass)
glseries_sequence integer
glseries_doctype character(2)
glseries_docnumber text
glseries_accnt_id integer
glseries_amount numeric(20,2)
glseries_source text
glseries_distdate date
glseries_notes text
glseries_misc_id integer

Index - Schema public


Table: public.gltrans

General Ledger (G/L) transaction information

public.gltrans Structure
F-Key Name Type Description
gltrans_id integer PRIMARY KEY DEFAULT nextval(('"gltrans_gltrans_id_seq"'::text)::regclass)
gltrans_exported boolean
gltrans_created timestamp with time zone
gltrans_date date NOT NULL
gltrans_sequence integer
gltrans_accnt_id integer NOT NULL
gltrans_source text
gltrans_docnumber text
gltrans_misc_id integer
gltrans_amount numeric(20,2) NOT NULL
gltrans_notes text
gltrans_journalnumber integer
gltrans_posted boolean NOT NULL
gltrans_doctype text
gltrans_rec boolean NOT NULL DEFAULT false
gltrans_username text NOT NULL DEFAULT geteffectivextuser()
gltrans_deleted boolean DEFAULT false
gltrans_gltrans_accnt_id_idx gltrans_accnt_id gltrans_gltrans_date_idx gltrans_date gltrans_gltrans_journalnumber_idx gltrans_journalnumber gltrans_sequence_idx gltrans_sequence

Index - Schema public


Table: public.grp

This table is the basic group information.

public.grp Structure
F-Key Name Type Description
grp_id serial PRIMARY KEY
grp_name text UNIQUE NOT NULL
grp_descrip text

 

public.grp Constraints
Name Constraint
grp_grp_name_check CHECK ((grp_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.grppriv

This is a specific priv for a specific group.

public.grppriv Structure
F-Key Name Type Description
grppriv_id serial PRIMARY KEY
public.grp.grp_id grppriv_grp_id integer NOT NULL
grppriv_priv_id integer NOT NULL

Index - Schema public


Table: public.hnfc

List of personal titles/honorifics used in cntct table.

public.hnfc Structure
F-Key Name Type Description
hnfc_id serial PRIMARY KEY
hnfc_code text UNIQUE NOT NULL

 

public.hnfc Constraints
Name Constraint
hnfc_hnfc_code_check CHECK ((hnfc_code <> ''::text))

Index - Schema public


Table: public.image

Image information

public.image Structure
F-Key Name Type Description
image_id integer PRIMARY KEY DEFAULT nextval(('"image_image_id_seq"'::text)::regclass)
image_name text
image_descrip text
image_data text

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.imageass

Image Assignement References

public.imageass Structure
F-Key Name Type Description
imageass_id integer PRIMARY KEY DEFAULT nextval('docass_docass_id_seq'::regclass)
imageass_source_id integer NOT NULL
imageass_source text NOT NULL
imageass_image_id integer NOT NULL
imageass_purpose character(1) NOT NULL

 

public.imageass Constraints
Name Constraint
imageass_imageass_purpose_check CHECK (((((((((imageass_purpose = 'I'::bpchar) OR (imageass_purpose = 'E'::bpchar)) OR (imageass_purpose = 'M'::bpchar)) OR (imageass_purpose = 'P'::bpchar)) OR (imageass_purpose = 'A'::bpchar)) OR (imageass_purpose = 'C'::bpchar)) OR (imageass_purpose = 'D'::bpchar)) OR (imageass_purpose = 'S'::bpchar)))

Index - Schema public


Table: public.incdt

Incident table

public.incdt Structure
F-Key Name Type Description
incdt_id serial PRIMARY KEY
incdt_number integer UNIQUE NOT NULL
public.crmacct.crmacct_id incdt_crmacct_id integer
public.cntct.cntct_id incdt_cntct_id integer
incdt_summary text
incdt_descrip text
public.item.item_id incdt_item_id integer
incdt_timestamp timestamp without time zone NOT NULL DEFAULT now()
incdt_status character(1) NOT NULL DEFAULT 'N'::bpchar
incdt_assigned_username text
public.incdtcat.incdtcat_id incdt_incdtcat_id integer
public.incdtseverity.incdtseverity_id incdt_incdtseverity_id integer
public.incdtpriority.incdtpriority_id incdt_incdtpriority_id integer
public.incdtresolution.incdtresolution_id incdt_incdtresolution_id integer
incdt_lotserial text

incdt_lotserial is deprecated
incdt_ls_id integer
public.aropen.aropen_id incdt_aropen_id integer
incdt_owner_username text
public.incdt.incdt_id incdt_recurring_incdt_id integer

The first incdt record in the series if this is a recurring Incident. If the incdt_recurring_incdt_id is the same as the incdt_id, this record is the first in the series.
incdt_updated timestamp without time zone NOT NULL DEFAULT now()
public.prj.prj_id incdt_prj_id integer
incdt_public boolean

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.incdtcat

Incident Category table

public.incdtcat Structure
F-Key Name Type Description
incdtcat_id serial PRIMARY KEY
incdtcat_name text UNIQUE NOT NULL
incdtcat_order integer
incdtcat_descrip text
incdtcat_ediprofile_id integer

 

public.incdtcat Constraints
Name Constraint
incdtcat_incdtcat_name_check CHECK ((incdtcat_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.incdthist

Incident history changes

public.incdthist Structure
F-Key Name Type Description
incdthist_id serial PRIMARY KEY
public.incdt.incdt_id incdthist_incdt_id integer NOT NULL
incdthist_change character(1)
incdthist_target_id integer
incdthist_timestamp timestamp without time zone NOT NULL DEFAULT now()
incdthist_username text NOT NULL DEFAULT geteffectivextuser()
incdthist_descrip text

Index - Schema public


Table: public.incdtpriority

Incident Priority table

public.incdtpriority Structure
F-Key Name Type Description
incdtpriority_id serial PRIMARY KEY
incdtpriority_name text UNIQUE NOT NULL
incdtpriority_order integer
incdtpriority_descrip text

 

public.incdtpriority Constraints
Name Constraint
incdtpriority_incdtpriority_name_check CHECK ((incdtpriority_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.incdtresolution

Incident Resolution table

public.incdtresolution Structure
F-Key Name Type Description
incdtresolution_id serial PRIMARY KEY
incdtresolution_name text UNIQUE NOT NULL
incdtresolution_order integer
incdtresolution_descrip text

 

public.incdtresolution Constraints
Name Constraint
incdtresolution_incdtresolution_name_check CHECK ((incdtresolution_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.incdtseverity

Incident Severity table

public.incdtseverity Structure
F-Key Name Type Description
incdtseverity_id serial PRIMARY KEY
incdtseverity_name text UNIQUE NOT NULL
incdtseverity_order integer
incdtseverity_descrip text

 

public.incdtseverity Constraints
Name Constraint
incdtseverity_incdtseverity_name_check CHECK ((incdtseverity_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.invbal

public.invbal Structure
F-Key Name Type Description
invbal_id serial PRIMARY KEY
public.period.period_id invbal_period_id integer
public.itemsite.itemsite_id invbal_itemsite_id integer
invbal_qoh_beginning numeric(18,6) NOT NULL
invbal_qoh_ending numeric(18,6) NOT NULL
invbal_qty_in numeric(18,6) NOT NULL
invbal_qty_out numeric(18,6) NOT NULL
invbal_value_beginning numeric(12,2) NOT NULL
invbal_value_ending numeric(12,2) NOT NULL
invbal_value_in numeric(12,2) NOT NULL
invbal_value_out numeric(12,2) NOT NULL
invbal_nn_beginning numeric(18,6) NOT NULL
invbal_nn_ending numeric(18,6) NOT NULL
invbal_nn_in numeric(18,6) NOT NULL
invbal_nn_out numeric(18,6) NOT NULL
invbal_nnval_beginning numeric(12,2) NOT NULL
invbal_nnval_ending numeric(12,2) NOT NULL
invbal_nnval_in numeric(12,2) NOT NULL
invbal_nnval_out numeric(12,2) NOT NULL
invbal_dirty boolean NOT NULL DEFAULT true

Index - Schema public


Table: public.invchead

Invoice header information

public.invchead Structure
F-Key Name Type Description
invchead_id serial PRIMARY KEY
invchead_cust_id integer NOT NULL
invchead_shipto_id integer
invchead_ordernumber text
invchead_orderdate date
invchead_posted boolean NOT NULL
invchead_printed boolean NOT NULL
invchead_invcnumber text UNIQUE NOT NULL
invchead_invcdate date NOT NULL
invchead_shipdate date
invchead_ponumber text
invchead_shipvia text
invchead_fob text
invchead_billto_name text
invchead_billto_address1 text
invchead_billto_address2 text
invchead_billto_address3 text
invchead_billto_city text
invchead_billto_state text
invchead_billto_zipcode text
invchead_billto_phone text
invchead_shipto_name text
invchead_shipto_address1 text
invchead_shipto_address2 text
invchead_shipto_address3 text
invchead_shipto_city text
invchead_shipto_state text
invchead_shipto_zipcode text
invchead_shipto_phone text
invchead_salesrep_id integer
invchead_commission numeric(20,10) NOT NULL
invchead_terms_id integer
invchead_freight numeric(16,2) NOT NULL
invchead_misc_amount numeric(16,2) NOT NULL
invchead_misc_descrip text
invchead_misc_accnt_id integer
invchead_payment numeric(16,2)
invchead_paymentref text
invchead_notes text
invchead_billto_country text
invchead_shipto_country text
invchead_prj_id integer
public.curr_symbol.curr_id invchead_curr_id integer DEFAULT basecurrid()
invchead_gldistdate date
invchead_recurring boolean NOT NULL DEFAULT false

Deprecated.
invchead_recurring_interval integer

Deprecated.
invchead_recurring_type text

Deprecated.
invchead_recurring_until date

Deprecated.
invchead_recurring_invchead_id integer
invchead_shipchrg_id integer
public.taxzone.taxzone_id invchead_taxzone_id integer
invchead_void boolean DEFAULT false
public.saletype.saletype_id invchead_saletype_id integer

Associated sale type for invoice.
public.shipzone.shipzone_id invchead_shipzone_id integer

Associated shipping zone for invoice.

 

public.invchead Constraints
Name Constraint
invchead_invchead_invcnumber_check CHECK ((invchead_invcnumber <> ''::text))

Tables referencing this one via Foreign Key Constraints:

invchead_invchead_ordernumber_idx invchead_ordernumber

Index - Schema public


Table: public.invcheadtax

public.invcheadtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.invchead.invchead_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.invcheadtax Inherits taxhist,

Index - Schema public


Table: public.invcitem

Invoice Line Item information

public.invcitem Structure
F-Key Name Type Description
invcitem_id serial PRIMARY KEY
public.invchead.invchead_id invcitem_invchead_id integer UNIQUE#1 NOT NULL
invcitem_linenumber integer UNIQUE#1
invcitem_item_id integer
invcitem_warehous_id integer DEFAULT (-1)
invcitem_custpn text
invcitem_number text
invcitem_descrip text
invcitem_ordered numeric(20,6) NOT NULL
invcitem_billed numeric(20,6) NOT NULL
invcitem_custprice numeric(20,4)
invcitem_price numeric(20,4) NOT NULL
invcitem_notes text
invcitem_salescat_id integer
public.taxtype.taxtype_id invcitem_taxtype_id integer
public.uom.uom_id invcitem_qty_uom_id integer
invcitem_qty_invuomratio numeric(20,10) NOT NULL
public.uom.uom_id invcitem_price_uom_id integer
invcitem_price_invuomratio numeric(20,10) NOT NULL
invcitem_coitem_id integer
invcitem_updateinv boolean DEFAULT false
public.accnt.accnt_id invcitem_rev_accnt_id integer

Tables referencing this one via Foreign Key Constraints:

invcitem_invcitem_invchead_id_idx invcitem_invchead_id invcitem_invcitem_itemsite_id_idx invcitem_item_id, invcitem_warehous_id

Index - Schema public


Table: public.invcitemtax

public.invcitemtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.invcitem.invcitem_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.invcitemtax Inherits taxhist,

invcitemtax_taxhist_parent_id_idx taxhist_parent_id

Index - Schema public


Table: public.invcnt

Count Tag information

public.invcnt Structure
F-Key Name Type Description
invcnt_id integer PRIMARY KEY DEFAULT nextval(('invcnt_invcnt_id_seq'::text)::regclass)
invcnt_itemsite_id integer
invcnt_tagdate timestamp with time zone
invcnt_cntdate timestamp with time zone
invcnt_qoh_before numeric(18,6)
invcnt_qoh_after numeric(18,6)
invcnt_matcost numeric(16,6)
invcnt_posted boolean
invcnt_postdate timestamp with time zone
invcnt_comments text
invcnt_priority boolean
invcnt_tagnumber text
invcnt_invhist_id integer
invcnt_location_id integer
invcnt_cnt_username text
invcnt_post_username text
invcnt_tag_username text

Index - Schema public


Table: public.invdetail

Detailed Inventory transaction information for Lot/Serial and Multiple Location Control (MLC) Items

public.invdetail Structure
F-Key Name Type Description
invdetail_id integer PRIMARY KEY DEFAULT nextval(('"invdetail_invdetail_id_seq"'::text)::regclass)
invdetail_transtype character(2)
invdetail_invhist_id integer
invdetail_location_id integer
invdetail_qty numeric(18,6)
invdetail_comments text
invdetail_qty_before numeric(18,6)
invdetail_qty_after numeric(18,6)
invdetail_invcitem_id integer
invdetail_expiration date
invdetail_warrpurc date
invdetail_ls_id integer
invdetail_invdetail_invcitem_id_idx invdetail_invcitem_id invdetail_invdetail_invhist_id_idx invdetail_invhist_id

Index - Schema public


Table: public.invhist

Inventory transaction history

public.invhist Structure
F-Key Name Type Description
invhist_id integer PRIMARY KEY DEFAULT nextval(('invhist_invhist_id_seq'::text)::regclass)
invhist_itemsite_id integer
invhist_transdate timestamp with time zone DEFAULT ('now'::text)::timestamp(6) with time zone
invhist_transtype character(2)
invhist_invqty numeric(18,6)
invhist_invuom text
invhist_ordnumber text
invhist_docnumber text
invhist_qoh_before numeric(18,6)
invhist_qoh_after numeric(18,6)
invhist_unitcost numeric(16,6)
invhist_acct_id integer
invhist_xfer_warehous_id integer
invhist_comments text
invhist_posted boolean DEFAULT true
invhist_imported boolean
invhist_hasdetail boolean DEFAULT false
invhist_ordtype text
invhist_analyze boolean DEFAULT true
invhist_user text DEFAULT geteffectivextuser()
invhist_created timestamp with time zone NOT NULL DEFAULT now()
invhist_costmethod character(1) NOT NULL
invhist_value_before numeric(12,2) NOT NULL
invhist_value_after numeric(12,2) NOT NULL
invhist_series integer

Tables referencing this one via Foreign Key Constraints:

invhist_hasdetail invhist_hasdetail invhist_invhist_ordnumber_idx invhist_ordnumber invhist_itemsite_id invhist_itemsite_id invhist_series invhist_series invhist_transdate invhist_transdate invhist_transtype invhist_transtype

Index - Schema public


Table: public.invhistexpcat

Track the relationship between an EX transaction in the invhist table and the corresponding Expense Category.

public.invhistexpcat Structure
F-Key Name Type Description
invhistexpcat_id serial PRIMARY KEY
public.invhist.invhist_id invhistexpcat_invhist_id integer UNIQUE#1 NOT NULL
public.expcat.expcat_id invhistexpcat_expcat_id integer UNIQUE#1 NOT NULL

Index - Schema public


View: public.invoiceitem

Single point for invoice item (invcitem) calculations.

public.invoiceitem Structure
F-Key Name Type Description
invcitem_id integer
invcitem_invchead_id integer
invcitem_linenumber integer
invcitem_item_id integer
invcitem_warehous_id integer
invcitem_custpn text
invcitem_number text
invcitem_descrip text
invcitem_ordered numeric(20,6)
invcitem_billed numeric(20,6)
invcitem_custprice numeric(20,4)
invcitem_price numeric(20,4)
invcitem_notes text
invcitem_salescat_id integer
invcitem_taxtype_id integer
invcitem_qty_uom_id integer
invcitem_qty_invuomratio numeric(20,10)
invcitem_price_uom_id integer
invcitem_price_invuomratio numeric(20,10)
invcitem_coitem_id integer
invcitem_updateinv boolean
invcitem_rev_accnt_id integer
itemsite_id integer
cohead_number text
qty numeric
unitprice numeric
extprice numeric
baseextprice numeric
tax numeric
unitcost numeric
SELECT invcitem.invcitem_id
, invcitem.invcitem_invchead_id
, invcitem.invcitem_linenumber
, invcitem.invcitem_item_id
, invcitem.invcitem_warehous_id
, invcitem.invcitem_custpn
, invcitem.invcitem_number
, invcitem.invcitem_descrip
, invcitem.invcitem_ordered
, invcitem.invcitem_billed
, invcitem.invcitem_custprice
, invcitem.invcitem_price
, invcitem.invcitem_notes
, invcitem.invcitem_salescat_id
, invcitem.invcitem_taxtype_id
, invcitem.invcitem_qty_uom_id
, invcitem.invcitem_qty_invuomratio
, invcitem.invcitem_price_uom_id
, invcitem.invcitem_price_invuomratio
, invcitem.invcitem_coitem_id
, invcitem.invcitem_updateinv
, invcitem.invcitem_rev_accnt_id
, itemsite.itemsite_id
, cohead.cohead_number
, COALESCE
(
     (invcitem.invcitem_billed * invcitem.invcitem_qty_invuomratio)
     , (0)::numeric
) AS qty
, COALESCE
(
     (invcitem.invcitem_price / invcitem.invcitem_price_invuomratio)
     , (0)::numeric
) AS unitprice
, COALESCE
(round
     (
           (
                 (invcitem.invcitem_billed * invcitem.invcitem_qty_invuomratio) * 
                 (invcitem.invcitem_price / invcitem.invcitem_price_invuomratio)
           )
           , 2
     )
     , (0)::numeric
) AS extprice
, currtobase
(invchead.invchead_curr_id
     , COALESCE
     (round
           (
                 (
                       (invcitem.invcitem_billed * invcitem.invcitem_qty_invuomratio) * 
                       (invcitem.invcitem_price / invcitem.invcitem_price_invuomratio)
                 )
                 , 2
           )
           , (0)::numeric
     )
     , invchead.invchead_invcdate
) AS baseextprice
, (
SELECT COALESCE
     (sum
           (invcitemtax.taxhist_tax)
           , (0)::numeric
     ) AS "coalesce"
  FROM invcitemtax 
 WHERE (invcitemtax.taxhist_parent_id = invcitem.invcitem_id)
) AS tax
, (
     (
      SELECT COALESCE
           (sum
                 (shipitem.shipitem_value)
                 , (itemcost
                       (itemsite.itemsite_id) * invcitem.invcitem_billed
                 )
                 , (0)::numeric
           ) AS "coalesce"
        FROM shipitem 
       WHERE (shipitem.shipitem_invcitem_id = invcitem.invcitem_id)
     ) / CASE WHEN 
     (invcitem.invcitem_billed <> 
           (0)::numeric
     ) THEN 
     (invcitem.invcitem_billed * invcitem.invcitem_qty_invuomratio) ELSE 
     (1)::numeric END
) AS unitcost 
FROM (
     (
           (
                 (invcitem 
                    JOIN invchead 
                      ON (
                             (invchead.invchead_id = invcitem.invcitem_invchead_id)
                       )
                 )
         LEFT JOIN coitem 
                ON (
                       (coitem.coitem_id = invcitem.invcitem_coitem_id)
                 )
           )
   LEFT JOIN cohead 
          ON (
                 (cohead.cohead_id = coitem.coitem_cohead_id)
           )
     )
LEFT JOIN itemsite 
    ON (
           (
                 (itemsite.itemsite_item_id = invcitem.invcitem_item_id)
               AND (itemsite.itemsite_warehous_id = invcitem.invcitem_warehous_id)
           )
     )
);

Index - Schema public


Table: public.ipsass

Pricing Schedule assignment information

public.ipsass Structure
F-Key Name Type Description
ipsass_id serial PRIMARY KEY
public.ipshead.ipshead_id ipsass_ipshead_id integer UNIQUE#1 NOT NULL
ipsass_cust_id integer UNIQUE#1
ipsass_custtype_id integer UNIQUE#1
ipsass_custtype_pattern text UNIQUE#1
ipsass_shipto_id integer UNIQUE#1 DEFAULT (-1)
ipsass_shipto_pattern text UNIQUE#1

Index - Schema public


Table: public.ipsfreight

public.ipsfreight Structure
F-Key Name Type Description
ipsfreight_id serial PRIMARY KEY
public.ipshead.ipshead_id ipsfreight_ipshead_id integer NOT NULL
ipsfreight_qtybreak numeric NOT NULL
ipsfreight_price numeric NOT NULL
ipsfreight_type character(1) NOT NULL
public.whsinfo.warehous_id ipsfreight_warehous_id integer
public.shipzone.shipzone_id ipsfreight_shipzone_id integer
public.freightclass.freightclass_id ipsfreight_freightclass_id integer
ipsfreight_shipvia text

Index - Schema public


Table: public.ipshead

Pricing Schedule header information

public.ipshead Structure
F-Key Name Type Description
ipshead_id integer PRIMARY KEY DEFAULT nextval(('"ipshead_ipshead_id_seq"'::text)::regclass)
ipshead_name text UNIQUE NOT NULL
ipshead_descrip text
ipshead_effective date
ipshead_expires date
public.curr_symbol.curr_id ipshead_curr_id integer NOT NULL DEFAULT basecurrid()
ipshead_updated date

 

public.ipshead Constraints
Name Constraint
ipshead_ipshead_name_check CHECK ((ipshead_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.ipsitemchar

Item Price Schedule Characteristic Prices.

public.ipsitemchar Structure
F-Key Name Type Description
ipsitemchar_id serial PRIMARY KEY
public.ipsiteminfo.ipsitem_id ipsitemchar_ipsitem_id integer UNIQUE#1 UNIQUE#2 NOT NULL
public.char.char_id ipsitemchar_char_id integer UNIQUE#1 UNIQUE#2 NOT NULL
ipsitemchar_value text UNIQUE#1 UNIQUE#2 NOT NULL
ipsitemchar_price numeric(16,4)

Index - Schema public


Table: public.ipsiteminfo

Pricing Schedule Item information

public.ipsiteminfo Structure
F-Key Name Type Description
ipsitem_id integer PRIMARY KEY DEFAULT nextval(('"ipsitem_ipsitem_id_seq"'::text)::regclass)
public.ipshead.ipshead_id ipsitem_ipshead_id integer UNIQUE#1
public.item.item_id ipsitem_item_id integer UNIQUE#1
ipsitem_qtybreak numeric(18,6) UNIQUE#1 NOT NULL
ipsitem_price numeric(16,4) NOT NULL
public.uom.uom_id ipsitem_qty_uom_id integer UNIQUE#1
public.uom.uom_id ipsitem_price_uom_id integer UNIQUE#1
ipsitem_discntprcnt numeric(10,6) NOT NULL DEFAULT 0.00
ipsitem_fixedamtdiscount numeric(16,4) NOT NULL DEFAULT 0.00
ipsitem_prodcat_id integer UNIQUE#1

Product category for pricing schedule item.
ipsitem_type character(1) NOT NULL

Pricing type for pricing schedule item. Valid values are N-nominal, D-discount, and M-markup
public.whsinfo.warehous_id ipsitem_warehous_id integer

Site for pricing schedule item which enables pricing by site.

 

public.ipsiteminfo Constraints
Name Constraint
valid_ipsitem_type CHECK ((ipsitem_type = ANY (ARRAY['N'::bpchar, 'D'::bpchar, 'M'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

ipsitem_ipshead_id_idx ipsitem_ipshead_id

Index - Schema public


View: public.ipsprice

public.ipsprice Structure
F-Key Name Type Description
ipsprice_id integer
ipsprice_source text
ipsprice_ipshead_id integer
ipsprice_item_id integer
ipsprice_qtybreak numeric
ipsprice_price numeric
ipsprice_uomqtybreak numeric(18,6)
ipsprice_uomqtybreak_uom_id integer
ipsprice_uomprice numeric
ipsprice_uomprice_uom_id integer
ipsprice_discountpercent numeric(10,6)
ipsprice_discountfixed numeric(16,4)
ipsprice_type character(1)
SELECT ipsiteminfo.ipsitem_id AS ipsprice_id
,'I' AS ipsprice_source
, ipsiteminfo.ipsitem_ipshead_id AS ipsprice_ipshead_id
, ipsiteminfo.ipsitem_item_id AS ipsprice_item_id
, itemuomtouom
(ipsiteminfo.ipsitem_item_id
     , ipsiteminfo.ipsitem_qty_uom_id
     , NULL::integer
     , ipsiteminfo.ipsitem_qtybreak
) AS ipsprice_qtybreak
, CASE WHEN 
(ipsiteminfo.ipsitem_type = 'N'::bpchar) THEN 
(
     (ipsiteminfo.ipsitem_price * itemuomtouomratio
           (ipsiteminfo.ipsitem_item_id
                 , NULL::integer
                 , ipsiteminfo.ipsitem_price_uom_id
           )
     ) * iteminvpricerat
     (ipsiteminfo.ipsitem_item_id)
) WHEN 
(ipsiteminfo.ipsitem_type = 'D'::bpchar) THEN 
(
     (item.item_listprice - 
           (item.item_listprice * ipsiteminfo.ipsitem_discntprcnt)
     ) - ipsiteminfo.ipsitem_fixedamtdiscount
) WHEN 
(ipsiteminfo.ipsitem_type = 'M'::bpchar) THEN 
(
     (item.item_listcost + 
           (item.item_listcost * ipsiteminfo.ipsitem_discntprcnt)
     ) + ipsiteminfo.ipsitem_fixedamtdiscount
) ELSE NULL::numeric END AS ipsprice_price
, ipsiteminfo.ipsitem_qtybreak AS ipsprice_uomqtybreak
, ipsiteminfo.ipsitem_qty_uom_id AS ipsprice_uomqtybreak_uom_id
, CASE WHEN 
(ipsiteminfo.ipsitem_type = 'N'::bpchar) THEN ipsiteminfo.ipsitem_price WHEN 
(ipsiteminfo.ipsitem_type = 'D'::bpchar) THEN 
(
     (item.item_listprice - 
           (item.item_listprice * ipsiteminfo.ipsitem_discntprcnt)
     ) - ipsiteminfo.ipsitem_fixedamtdiscount
) WHEN 
(ipsiteminfo.ipsitem_type = 'M'::bpchar) THEN 
(
     (item.item_listcost + 
           (item.item_listcost * ipsiteminfo.ipsitem_discntprcnt)
     ) + ipsiteminfo.ipsitem_fixedamtdiscount
) ELSE NULL::numeric END AS ipsprice_uomprice
, ipsiteminfo.ipsitem_price_uom_id AS ipsprice_uomprice_uom_id
, ipsiteminfo.ipsitem_discntprcnt AS ipsprice_discountpercent
, ipsiteminfo.ipsitem_fixedamtdiscount AS ipsprice_discountfixed
, ipsiteminfo.ipsitem_type AS ipsprice_type 
FROM (ipsiteminfo 
  JOIN item 
    ON (
           (item.item_id = ipsiteminfo.ipsitem_item_id)
     )
)
UNIONSELECT ipsiteminfo.ipsitem_id AS ipsprice_id
,'P' AS ipsprice_source
, ipsiteminfo.ipsitem_ipshead_id AS ipsprice_ipshead_id
, item.item_id AS ipsprice_item_id
, ipsiteminfo.ipsitem_qtybreak AS ipsprice_qtybreak
, CASE WHEN 
(ipsiteminfo.ipsitem_type = 'D'::bpchar) THEN 
(
     (item.item_listprice - 
           (item.item_listprice * ipsiteminfo.ipsitem_discntprcnt)
     ) - ipsiteminfo.ipsitem_fixedamtdiscount
) WHEN 
(ipsiteminfo.ipsitem_type = 'M'::bpchar) THEN 
(
     (item.item_listcost + 
           (item.item_listcost * ipsiteminfo.ipsitem_discntprcnt)
     ) + ipsiteminfo.ipsitem_fixedamtdiscount
) ELSE NULL::numeric END AS ipsprice_price
, ipsiteminfo.ipsitem_qtybreak AS ipsprice_uomqtybreak
, item.item_inv_uom_id AS ipsprice_uomqtybreak_uom_id
, CASE WHEN 
(ipsiteminfo.ipsitem_type = 'D'::bpchar) THEN 
(
     (item.item_listprice - 
           (item.item_listprice * ipsiteminfo.ipsitem_discntprcnt)
     ) - ipsiteminfo.ipsitem_fixedamtdiscount
) WHEN 
(ipsiteminfo.ipsitem_type = 'M'::bpchar) THEN 
(
     (item.item_listcost + 
           (item.item_listcost * ipsiteminfo.ipsitem_discntprcnt)
     ) + ipsiteminfo.ipsitem_fixedamtdiscount
) ELSE NULL::numeric END AS ipsprice_uomprice
, item.item_price_uom_id AS ipsprice_uomprice_uom_id
, ipsiteminfo.ipsitem_discntprcnt AS ipsprice_discountpercent
, ipsiteminfo.ipsitem_fixedamtdiscount AS ipsprice_discountfixed
, ipsiteminfo.ipsitem_type AS ipsprice_type 
FROM (ipsiteminfo 
  JOIN item 
    ON (
           (ipsiteminfo.ipsitem_prodcat_id = item.item_prodcat_id)
     )
);

Index - Schema public


Table: public.ipsprodcat_bak

Pricing Schedule Product Category information.

public.ipsprodcat_bak Structure
F-Key Name Type Description
ipsprodcat_id serial PRIMARY KEY
ipsprodcat_ipshead_id integer NOT NULL
ipsprodcat_prodcat_id integer NOT NULL
ipsprodcat_qtybreak numeric(18,6) NOT NULL
ipsprodcat_discntprcnt numeric(10,6) NOT NULL
ipsprodcat_fixedamtdiscount numeric(16,4) NOT NULL DEFAULT 0.00

Index - Schema public


Table: public.item

Item information

public.item Structure
F-Key Name Type Description
item_id integer PRIMARY KEY DEFAULT nextval(('item_item_id_seq'::text)::regclass)
item_number text UNIQUE NOT NULL
item_descrip1 text NOT NULL
item_descrip2 text NOT NULL
public.classcode.classcode_id item_classcode_id integer NOT NULL
item_picklist boolean NOT NULL DEFAULT true
item_comments text
item_sold boolean NOT NULL
item_fractional boolean NOT NULL
item_active boolean NOT NULL
item_type character(1) NOT NULL DEFAULT 'R'::bpchar
item_prodweight numeric(16,2) NOT NULL
item_packweight numeric(16,2) NOT NULL
item_prodcat_id integer NOT NULL
item_exclusive boolean NOT NULL DEFAULT false
item_listprice numeric(16,4) NOT NULL
item_config boolean DEFAULT false
item_extdescrip text
item_upccode text
item_maxcost numeric(16,6) NOT NULL

Maximum cost for item. Used to constrain purchase order price.
public.uom.uom_id item_inv_uom_id integer NOT NULL
public.uom.uom_id item_price_uom_id integer NOT NULL
item_warrdays integer
public.freightclass.freightclass_id item_freightclass_id integer
item_tax_recoverable boolean NOT NULL DEFAULT false
item_listcost numeric(16,6) NOT NULL DEFAULT 0.0

List cost for item. Basis for markup pricing.

 

public.item Constraints
Name Constraint
item_item_number_check CHECK ((item_number <> ''::text))
item_item_type_check CHECK (((((((((((((item_type = 'P'::bpchar) OR (item_type = 'M'::bpchar)) OR (item_type = 'F'::bpchar)) OR (item_type = 'O'::bpchar)) OR (item_type = 'R'::bpchar)) OR (item_type = 'S'::bpchar)) OR (item_type = 'T'::bpchar)) OR (item_type = 'B'::bpchar)) OR (item_type = 'L'::bpchar)) OR (item_type = 'Y'::bpchar)) OR (item_type = 'C'::bpchar)) OR (item_type = 'K'::bpchar)))
item_sold_check CHECK ((NOT (item_sold AND (item_prodcat_id = (-1)))))

Tables referencing this one via Foreign Key Constraints:

item_classcode_id item_classcode_id item_prodcat_id_idx item_prodcat_id item_upccode_idx item_upccode

Index - Schema public


Table: public.itemalias

Item Alias information

public.itemalias Structure
F-Key Name Type Description
itemalias_id integer PRIMARY KEY DEFAULT nextval(('"itemalias_itemalias_id_seq"'::text)::regclass)
public.item.item_id itemalias_item_id integer UNIQUE#1 NOT NULL
itemalias_number text UNIQUE#1 NOT NULL
itemalias_comments text
itemalias_usedescrip boolean NOT NULL
itemalias_descrip1 text
itemalias_descrip2 text

 

public.itemalias Constraints
Name Constraint
itemalias_itemalias_number_check CHECK ((itemalias_number <> ''::text))

Index - Schema public


Table: public.itemcost

Item Cost information

public.itemcost Structure
F-Key Name Type Description
itemcost_id integer PRIMARY KEY DEFAULT nextval(('itemcost_itemcost_id_seq'::text)::regclass)
public.item.item_id itemcost_item_id integer NOT NULL
public.costelem.costelem_id itemcost_costelem_id integer NOT NULL
itemcost_lowlevel boolean NOT NULL DEFAULT false
itemcost_stdcost numeric(16,6) NOT NULL
itemcost_posted date
itemcost_actcost numeric(16,6) NOT NULL
itemcost_updated date
public.curr_symbol.curr_id public.curr_symbol.curr_id itemcost_curr_id integer NOT NULL DEFAULT basecurrid()
itemcost_item_id_key itemcost_item_id

Index - Schema public


Table: public.itemgrp

Item Group information

public.itemgrp Structure
F-Key Name Type Description
itemgrp_id integer PRIMARY KEY DEFAULT nextval(('"itemgrp_itemgrp_id_seq"'::text)::regclass)
itemgrp_name text UNIQUE NOT NULL
itemgrp_descrip text

 

public.itemgrp Constraints
Name Constraint
itemgrp_itemgrp_name_check CHECK ((itemgrp_name <> ''::text))

Index - Schema public


Table: public.itemgrpitem

Item Group Item information

public.itemgrpitem Structure
F-Key Name Type Description
itemgrpitem_id integer PRIMARY KEY DEFAULT nextval(('"itemgrpitem_itemgrpitem_id_seq"'::text)::regclass)
itemgrpitem_itemgrp_id integer
itemgrpitem_item_id integer

Index - Schema public


View: public.itemimage

Itemimage view for legacy support. Use of itemimage is deprecated. Use imageass table for future development

public.itemimage Structure
F-Key Name Type Description
itemimage_id integer
itemimage_item_id integer
itemimage_image_id integer
itemimage_purpose character(1)
SELECT imageass.imageass_id AS itemimage_id
, imageass.imageass_source_id AS itemimage_item_id
, imageass.imageass_image_id AS itemimage_image_id
, imageass.imageass_purpose AS itemimage_purpose 
FROM imageass 
WHERE (imageass.imageass_source = 'I'::text);

Index - Schema public


Table: public.itemloc

Detailed Location information for Lot/Serial and Multiple Location Control (MLC) Items

public.itemloc Structure
F-Key Name Type Description
itemloc_id integer PRIMARY KEY DEFAULT nextval(('"itemloc_itemloc_id_seq"'::text)::regclass)
itemloc_itemsite_id integer NOT NULL
itemloc_location_id integer NOT NULL
itemloc_qty numeric(18,6) NOT NULL
itemloc_expiration date NOT NULL
itemloc_consolflag boolean
itemloc_ls_id integer
itemloc_warrpurc date
itemloc_itemsite_idx itemloc_itemsite_id itemloc_location_idx itemloc_location_id

Index - Schema public


Table: public.itemlocdist

Temporary table for storing information about Inventory distributions involving Lot/Serial and Multiple Location Control (MLC) Items

public.itemlocdist Structure
F-Key Name Type Description
itemlocdist_id integer PRIMARY KEY DEFAULT nextval(('"itemlocdist_itemlocdist_id_seq"'::text)::regclass)
itemlocdist_itemlocdist_id integer
itemlocdist_source_type character(1)
itemlocdist_source_id integer
itemlocdist_qty numeric(18,6)
itemlocdist_series integer
itemlocdist_invhist_id integer
itemlocdist_itemsite_id integer
itemlocdist_reqlotserial boolean DEFAULT false
itemlocdist_flush boolean DEFAULT false
itemlocdist_expiration date
itemlocdist_distlotserial boolean
itemlocdist_warranty date
itemlocdist_ls_id integer
itemlocdist_order_type text
itemlocdist_order_id integer

Index - Schema public


Table: public.itemlocpost

Temporary table for storing information about Inventory distribution G/L postings involving Lot/Serial and Multiple Location Control (MLC) Items

public.itemlocpost Structure
F-Key Name Type Description
itemlocpost_id serial PRIMARY KEY
itemlocpost_itemlocseries integer
itemlocpost_glseq integer

Index - Schema public


Table: public.itemsite

Item Site information

public.itemsite Structure
F-Key Name Type Description
itemsite_id integer PRIMARY KEY DEFAULT nextval(('itemsite_itemsite_id_seq'::text)::regclass)
public.item.item_id itemsite_item_id integer NOT NULL
public.whsinfo.warehous_id itemsite_warehous_id integer
itemsite_qtyonhand numeric(18,6) NOT NULL
itemsite_reorderlevel numeric(18,6) NOT NULL
itemsite_ordertoqty numeric(18,6) NOT NULL
itemsite_cyclecountfreq integer NOT NULL
itemsite_datelastcount date
itemsite_datelastused date
itemsite_loccntrl boolean NOT NULL
itemsite_safetystock numeric(18,6) NOT NULL
itemsite_minordqty numeric(18,6) NOT NULL
itemsite_multordqty numeric(18,6) NOT NULL
itemsite_leadtime integer NOT NULL
itemsite_abcclass character(1)
itemsite_issuemethod character(1)
itemsite_controlmethod character(1)
itemsite_active boolean NOT NULL
public.plancode.plancode_id itemsite_plancode_id integer NOT NULL
public.costcat.costcat_id itemsite_costcat_id integer NOT NULL
itemsite_eventfence integer NOT NULL
itemsite_sold boolean NOT NULL
itemsite_stocked boolean NOT NULL
itemsite_freeze boolean NOT NULL DEFAULT false
itemsite_location_id integer NOT NULL
itemsite_useparams boolean NOT NULL
itemsite_useparamsmanual boolean NOT NULL
itemsite_soldranking integer DEFAULT 1
itemsite_createpr boolean
itemsite_location text
itemsite_location_comments text
itemsite_notes text
itemsite_perishable boolean NOT NULL
itemsite_nnqoh numeric(18,6) NOT NULL
itemsite_autoabcclass boolean NOT NULL
itemsite_ordergroup integer NOT NULL DEFAULT 1
itemsite_disallowblankwip boolean NOT NULL DEFAULT false
itemsite_maxordqty numeric(18,6) NOT NULL DEFAULT 0.0
itemsite_mps_timefence integer NOT NULL
itemsite_createwo boolean NOT NULL DEFAULT false
itemsite_warrpurc boolean NOT NULL DEFAULT false
itemsite_autoreg boolean DEFAULT false
itemsite_costmethod character(1) NOT NULL
itemsite_value numeric(12,2) NOT NULL
itemsite_ordergroup_first boolean NOT NULL DEFAULT false
itemsite_supply_itemsite_id integer
itemsite_planning_type character(1) NOT NULL DEFAULT 'M'::bpchar
itemsite_wosupply boolean NOT NULL DEFAULT false
itemsite_posupply boolean NOT NULL DEFAULT false
itemsite_lsseq_id integer

Foreign key reference for automatic lot/serial numbering
itemsite_cosdefault character(1)
itemsite_createsopr boolean DEFAULT false

Used to flag Sales items that create P/Rs
itemsite_createsopo boolean DEFAULT false

Used to flag Sales items that create P/Os
itemsite_dropship boolean DEFAULT false

Used to flag Sales items to drop ship
itemsite_recvlocation_id integer NOT NULL DEFAULT (-1)
itemsite_issuelocation_id integer NOT NULL DEFAULT (-1)
itemsite_location_dist boolean NOT NULL DEFAULT false
itemsite_recvlocation_dist boolean NOT NULL DEFAULT false
itemsite_issuelocation_dist boolean NOT NULL DEFAULT false

 

public.itemsite Constraints
Name Constraint
itemsite_itemsite_abcclass_check CHECK (((((itemsite_abcclass = 'A'::bpchar) OR (itemsite_abcclass = 'B'::bpchar)) OR (itemsite_abcclass = 'C'::bpchar)) OR (itemsite_abcclass = 'T'::bpchar)))
itemsite_itemsite_controlmethod_check CHECK (((((itemsite_controlmethod = 'N'::bpchar) OR (itemsite_controlmethod = 'R'::bpchar)) OR (itemsite_controlmethod = 'S'::bpchar)) OR (itemsite_controlmethod = 'L'::bpchar)))
itemsite_itemsite_costmethod_check CHECK (((((itemsite_costmethod = 'N'::bpchar) OR (itemsite_costmethod = 'A'::bpchar)) OR (itemsite_costmethod = 'S'::bpchar)) OR (itemsite_costmethod = 'J'::bpchar)))
itemsite_itemsite_ordergroup_check CHECK ((itemsite_ordergroup > 0))

Tables referencing this one via Foreign Key Constraints:

itemsite_active_key itemsite_active itemsite_item_id_key itemsite_item_id itemsite_plancode_id_key itemsite_plancode_id itemsite_warehous_id_key itemsite_warehous_id

Index - Schema public


Table: public.itemsrc

Item Source information

public.itemsrc Structure
F-Key Name Type Description
itemsrc_id integer PRIMARY KEY DEFAULT nextval(('"itemsrc_itemsrc_id_seq"'::text)::regclass)
public.item.item_id itemsrc_item_id integer UNIQUE#1 NOT NULL
public.vendinfo.vend_id itemsrc_vend_id integer UNIQUE#1 NOT NULL
itemsrc_vend_item_number text UNIQUE#1
itemsrc_vend_item_descrip text
itemsrc_comments text
itemsrc_vend_uom text NOT NULL
itemsrc_invvendoruomratio numeric(20,10) NOT NULL
itemsrc_minordqty numeric(18,6) NOT NULL
itemsrc_multordqty numeric(18,6) NOT NULL
itemsrc_leadtime integer NOT NULL
itemsrc_ranking integer NOT NULL
itemsrc_active boolean NOT NULL
itemsrc_manuf_name text UNIQUE#1 NOT NULL DEFAULT ''::text
itemsrc_manuf_item_number text UNIQUE#1 NOT NULL DEFAULT ''::text
itemsrc_manuf_item_descrip text
itemsrc_default boolean
itemsrc_upccode text
itemsrc_effective date UNIQUE#1 NOT NULL DEFAULT startoftime()

Effective date for item source. Constraint for overlap.
itemsrc_expires date UNIQUE#1 NOT NULL DEFAULT endoftime()

Expiration date for item source. Constraint for overlap.
public.contrct.contrct_id itemsrc_contrct_id integer

Associated contract for item source. Inherits effective, expiration dates.

Tables referencing this one via Foreign Key Constraints:

itemsrc_vend_id_idx itemsrc_vend_id

Index - Schema public


Table: public.itemsrcp

Item Source Price information

public.itemsrcp Structure
F-Key Name Type Description
itemsrcp_id integer PRIMARY KEY DEFAULT nextval(('itemsrcp_itemsrcp_id_seq'::text)::regclass)
public.itemsrc.itemsrc_id itemsrcp_itemsrc_id integer UNIQUE#1 NOT NULL
itemsrcp_qtybreak numeric(18,6) UNIQUE#1 NOT NULL
itemsrcp_price numeric(16,6)
itemsrcp_updated date
public.curr_symbol.curr_id itemsrcp_curr_id integer NOT NULL DEFAULT basecurrid()
itemsrcp_dropship boolean UNIQUE#1 NOT NULL DEFAULT false

Used to determine if item source price applies only to drop ship purchase orders.
itemsrcp_warehous_id integer UNIQUE#1 NOT NULL DEFAULT (-1)

Used to determine if item source price applies only to specific site on purchase orders.
itemsrcp_type character(1) NOT NULL

Pricing type for item source price. Valid values are N-nominal and D-discount.
itemsrcp_discntprcnt numeric(16,6)

Discount percent for item source price.
itemsrcp_fixedamtdiscount numeric(16,6)

Fixed amount discount for item source price.

 

public.itemsrcp Constraints
Name Constraint
valid_itemsrcp_type CHECK ((itemsrcp_type = ANY (ARRAY['N'::bpchar, 'D'::bpchar])))
itemsrcp_itemsrc_id_key itemsrcp_itemsrc_id

Index - Schema public


Table: public.itemsub

Item Substitutes information

public.itemsub Structure
F-Key Name Type Description
itemsub_id integer PRIMARY KEY DEFAULT nextval(('itemsub_itemsub_id_seq'::text)::regclass)
public.item.item_id itemsub_parent_item_id integer UNIQUE#1 NOT NULL
public.item.item_id itemsub_sub_item_id integer UNIQUE#1 NOT NULL
itemsub_uomratio numeric(20,10) NOT NULL
itemsub_rank integer NOT NULL
itemsub_parent_item_id_key itemsub_parent_item_id itemsub_sub_item_id_key itemsub_sub_item_id

Index - Schema public


Table: public.itemtax

This table associates tax types in a specified tax authority for the given item.

public.itemtax Structure
F-Key Name Type Description
itemtax_id serial PRIMARY KEY
public.item.item_id itemtax_item_id integer NOT NULL
public.taxtype.taxtype_id itemtax_taxtype_id integer NOT NULL
public.taxzone.taxzone_id itemtax_taxzone_id integer

Index - Schema public


Table: public.itemtrans

Item Transformation information

public.itemtrans Structure
F-Key Name Type Description
itemtrans_id serial PRIMARY KEY
public.item.item_id itemtrans_source_item_id integer UNIQUE#1
public.item.item_id itemtrans_target_item_id integer UNIQUE#1

Index - Schema public


Table: public.itemuom

A UOM type relation for a specific conversion.

public.itemuom Structure
F-Key Name Type Description
itemuom_id serial PRIMARY KEY
public.itemuomconv.itemuomconv_id itemuom_itemuomconv_id integer NOT NULL
public.uomtype.uomtype_id itemuom_uomtype_id integer NOT NULL

Index - Schema public


Table: public.itemuomconv

UOM conversion information. From Unit to To Unit with a value per.

public.itemuomconv Structure
F-Key Name Type Description
itemuomconv_id serial PRIMARY KEY
public.item.item_id itemuomconv_item_id integer NOT NULL
public.uom.uom_id itemuomconv_from_uom_id integer NOT NULL
itemuomconv_from_value numeric(20,10) NOT NULL
public.uom.uom_id itemuomconv_to_uom_id integer NOT NULL
itemuomconv_to_value numeric(20,10) NOT NULL
itemuomconv_fractional boolean NOT NULL DEFAULT false

 

public.itemuomconv Constraints
Name Constraint
itemuomconv_uom CHECK ((itemuomconv_from_uom_id <> itemuomconv_to_uom_id))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.jrnluse

Journal entry and use information

public.jrnluse Structure
F-Key Name Type Description
jrnluse_id integer PRIMARY KEY DEFAULT nextval(('"jrnluse_jrnluse_id_seq"'::text)::regclass)
jrnluse_date timestamp without time zone
jrnluse_number integer
jrnluse_use text

Index - Schema public


Table: public.labeldef

public.labeldef Structure
F-Key Name Type Description
labeldef_id serial PRIMARY KEY
labeldef_name text NOT NULL
labeldef_papersize text NOT NULL
labeldef_columns integer NOT NULL
labeldef_rows integer NOT NULL
labeldef_width integer NOT NULL
labeldef_height integer NOT NULL
labeldef_start_offset_x integer NOT NULL
labeldef_start_offset_y integer NOT NULL
labeldef_horizontal_gap integer NOT NULL
labeldef_vertical_gap integer NOT NULL

Index - Schema public


Table: public.labelform

Label Form information

public.labelform Structure
F-Key Name Type Description
labelform_id integer PRIMARY KEY DEFAULT nextval(('"labelform_labelform_id_seq"'::text)::regclass)
labelform_name text UNIQUE NOT NULL
labelform_report_id integer

Obsolete -- reference labelform_report_name instead.
labelform_perpage integer
labelform_report_name text

 

public.labelform Constraints
Name Constraint
labelform_labelform_name_check CHECK ((labelform_name <> ''::text))

Index - Schema public


Table: public.lang

Table mapping ISO 639-1 and 639-2 language codes to Qt's enum QLocale::Language integer values. See http://www.loc.gov/standards/iso639-2/php/code_list.php and the QLocale documentation..

public.lang Structure
F-Key Name Type Description
lang_id serial PRIMARY KEY
lang_qt_number integer
lang_abbr3 text

ISO 639-2 code for language. Where there is a choice between bibliographic (B) and terminology (T) usage, this value is the T code
lang_abbr2 text

ISO 639-1 code for language
lang_name text NOT NULL

Name of a human language, taken from the ISO 639-2 documentation

Index - Schema public


Table: public.locale

The locale table holds information required to show data to the user in a localized format. Colors are either names documented by the WWW Consortium or RGB colors. Format for RGB colors is #RGB, #RRGGBB, or #RRRGGGBBB, where the letters R, G, and B stand for hexidecimal digits.

public.locale Structure
F-Key Name Type Description
locale_id integer PRIMARY KEY DEFAULT nextval(('locale_locale_id_seq'::text)::regclass)
locale_code text UNIQUE NOT NULL
locale_descrip text
locale_lang_file text

Deprecated
locale_dateformat text

Deprecated
locale_currformat text

Deprecated
locale_qtyformat text

Deprecated
locale_comments text
locale_qtyperformat text

Deprecated
locale_salespriceformat text

Deprecated
locale_extpriceformat text

Deprecated
locale_timeformat text

Deprecated
locale_timestampformat text

Deprecated
local_costformat text

Deprecated
locale_costformat text

Deprecated
locale_purchpriceformat text

Deprecated
locale_uomratioformat text

Deprecated
locale_intervalformat text

Deprecated
locale_lang_id integer
locale_country_id integer
locale_error_color text

Color to use to mark data that require immediate attention.
locale_warning_color text

Color to use to mark data that require attention soon.
locale_emphasis_color text

Color to use to mark data that need to stand out but are not in error.
locale_altemphasis_color text

Color to use to mark data that need to stand out and be differentiated from other emphasized data.
locale_expired_color text

Color to use to mark data that are no longer current.
locale_future_color text

Color to use to mark data that will not be effective until some point in the future.
locale_curr_scale integer

Number of decimal places to show when displaying Currency values.
locale_salesprice_scale integer

Number of decimal places to show when displaying Sales Prices.
locale_purchprice_scale integer

Number of decimal places to show when displaying Purchase Prices.
locale_extprice_scale integer

Number of decimal places to show when displaying Extended Prices.
locale_cost_scale integer

Number of decimal places to show when displaying Costs.
locale_qty_scale integer

Number of decimal places to show when displaying Quantities.
locale_qtyper_scale integer

Number of decimal places to show when displaying Quantities Per.
locale_uomratio_scale integer

Number of decimal places to show when displaying UOM Ratios.
locale_percent_scale integer DEFAULT 2
locale_weight_scale integer NOT NULL DEFAULT 2

 

public.locale Constraints
Name Constraint
locale_locale_code_check CHECK ((locale_code <> ''::text))

Index - Schema public


Table: public.location

Warehouse Location information

public.location Structure
F-Key Name Type Description
location_id integer PRIMARY KEY DEFAULT nextval(('location_location_id_seq'::text)::regclass)
location_warehous_id integer NOT NULL
location_name text NOT NULL
location_descrip text
location_restrict boolean
location_netable boolean
location_whsezone_id integer
location_aisle text
location_rack text
location_bin text
location_warehous_idx location_warehous_id

Index - Schema public


Table: public.locitem

Restricted Warehouse Location Allowable Items information

public.locitem Structure
F-Key Name Type Description
locitem_id integer PRIMARY KEY DEFAULT nextval(('"locitem_locitem_id_seq"'::text)::regclass)
locitem_location_id integer
locitem_item_id integer

Index - Schema public


Table: public.metasql

MetaSQL Table

public.metasql Structure
F-Key Name Type Description
metasql_id serial PRIMARY KEY
metasql_group text UNIQUE#1
metasql_name text UNIQUE#1
metasql_notes text
metasql_query text
metasql_lastuser text
metasql_lastupdate date
metasql_grade integer UNIQUE#1 NOT NULL

Index - Schema public


Table: public.metric

Application-wide settings information

public.metric Structure
F-Key Name Type Description
metric_id integer PRIMARY KEY DEFAULT nextval(('metric_metric_id_seq'::text)::regclass)
metric_name text UNIQUE NOT NULL
metric_value text
metric_module text

 

public.metric Constraints
Name Constraint
metric_metric_name_check CHECK ((metric_name <> ''::text))

Index - Schema public


Table: public.metricenc

Application-wide settings information encrypted data

public.metricenc Structure
F-Key Name Type Description
metricenc_id serial PRIMARY KEY
metricenc_name text UNIQUE NOT NULL
metricenc_value bytea
metricenc_module text

 

public.metricenc Constraints
Name Constraint
metricenc_metricenc_name_check CHECK ((metricenc_name <> ''::text))

Index - Schema public


Table: public.mrghist

public.mrghist Structure
F-Key Name Type Description
public.cntct.cntct_id mrghist_cntct_id integer PRIMARY KEY
mrghist_table text PRIMARY KEY
mrghist_pkey_col text PRIMARY KEY
mrghist_pkey_id integer PRIMARY KEY
mrghist_cntct_col text PRIMARY KEY

Index - Schema public


Table: public.mrgundo

This table keeps track of the original values of changes made while merging two records. It is a generalization of mrghist and trgthist, which are specific to merging contacts. The schema, table, and pkey_id columns uniquely identify the record that was changed while the _base_ columns identify the merge target. The _base_ columns are required to allow finding all of the records that pertain to a particular merge (e.g. find changes to the comment table that pertain to a crmacct merge).

public.mrgundo Structure
F-Key Name Type Description
mrgundo_base_schema text

The schema in which the merge target resides.
mrgundo_base_table text

The table in which the merge target resides.
mrgundo_base_id integer

The internal id of the merge target record.
mrgundo_schema text UNIQUE#1

The name of the schema in which the modified table resides.
mrgundo_table text UNIQUE#1

The name of the table that was modified during a merge.
mrgundo_pkey_col text UNIQUE#1

The name of the primary key column in the modified table. This could be derived during the undo processing but it is simpler just to store it during the merge.
mrgundo_pkey_id integer UNIQUE#1

The primary key of the modified record.
mrgundo_col text UNIQUE#1

The column that was modified.
mrgundo_value text

The value of the column before the change.
mrgundo_type text

The data type of the modified column. This could be derived during the undo processing but it is simpler just to store it during the merge.

Index - Schema public


Table: public.msg

System Message information

public.msg Structure
F-Key Name Type Description
msg_id integer PRIMARY KEY DEFAULT nextval(('"msg_msg_id_seq"'::text)::regclass)
msg_posted timestamp with time zone
msg_scheduled timestamp with time zone
msg_text text
msg_expires timestamp with time zone
msg_username text

Index - Schema public


Table: public.msguser

System Message user information

public.msguser Structure
F-Key Name Type Description
msguser_id integer PRIMARY KEY DEFAULT nextval(('"msguser_msguser_id_seq"'::text)::regclass)
msguser_msg_id integer
msguser_viewed timestamp with time zone
msguser_username text

Index - Schema public


Table: public.obsolete_tax

Tax information. Obsolete table structure.

public.obsolete_tax Structure
F-Key Name Type Description
tax_id integer PRIMARY KEY DEFAULT nextval(('"tax_tax_id_seq"'::text)::regclass)
tax_code text
tax_descrip text
tax_ratea numeric(8,4)
tax_sales_accnt_id integer
tax_freight boolean NOT NULL DEFAULT false

Deprecated in 2.1 and moved to taxsel table where taxtype is the system defined Freight.
tax_cumulative boolean NOT NULL DEFAULT false
tax_rateb numeric(8,4)
tax_salesb_accnt_id integer
tax_ratec numeric(8,4)
tax_salesc_accnt_id integer

Index - Schema public


Table: public.ophead

Opportunity header.

public.ophead Structure
F-Key Name Type Description
ophead_id serial PRIMARY KEY
ophead_name text NOT NULL
public.crmacct.crmacct_id ophead_crmacct_id integer
ophead_owner_username text
public.opstage.opstage_id ophead_opstage_id integer
public.opsource.opsource_id ophead_opsource_id integer
public.optype.optype_id ophead_optype_id integer
ophead_probability_prcnt integer
ophead_amount numeric(20,4)
ophead_target_date date
ophead_actual_date date
ophead_notes text
ophead_curr_id integer
ophead_active boolean DEFAULT true
public.cntct.cntct_id ophead_cntct_id integer
ophead_username text
ophead_start_date date
ophead_assigned_date date
public.incdtpriority.incdtpriority_id ophead_priority_id integer
ophead_number text UNIQUE NOT NULL

 

public.ophead Constraints
Name Constraint
ophead_ophead_number_check CHECK ((ophead_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.opsource

Opportunity Lead Source values.

public.opsource Structure
F-Key Name Type Description
opsource_id serial PRIMARY KEY
opsource_name text UNIQUE NOT NULL
opsource_descrip text

 

public.opsource Constraints
Name Constraint
opsource_opsource_name_check CHECK ((opsource_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.opstage

Opportunity stage values.

public.opstage Structure
F-Key Name Type Description
opstage_id serial PRIMARY KEY
opstage_name text UNIQUE NOT NULL
opstage_descrip text
opstage_order integer NOT NULL
opstage_opinactive boolean DEFAULT false

 

public.opstage Constraints
Name Constraint
opstage_opstage_name_check CHECK ((opstage_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.optype

Opportunity Type values.

public.optype Structure
F-Key Name Type Description
optype_id serial PRIMARY KEY
optype_name text UNIQUE NOT NULL
optype_descrip text

 

public.optype Constraints
Name Constraint
optype_optype_name_check CHECK ((optype_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


View: public.orderhead

Union of all orders for use by widgets and stored procedures which process multiple types of order

public.orderhead Structure
F-Key Name Type Description
orderhead_id integer
orderhead_type text
orderhead_number text
orderhead_status character(1)
orderhead_orderdate date
orderhead_linecount bigint
orderhead_from_id integer
orderhead_from text
orderhead_to_id integer
orderhead_to text
orderhead_curr_id integer
orderhead_agent_username text
orderhead_shipvia text
SELECT DISTINCT data.orderhead_id
, data.orderhead_type
, data.orderhead_number
, data.orderhead_status
, data.orderhead_orderdate
, data.orderhead_linecount
, data.orderhead_from_id
, data.orderhead_from
, data.orderhead_to_id
, data.orderhead_to
, data.orderhead_curr_id
, data.orderhead_agent_username
, data.orderhead_shipvia 
FROM (
SELECT pohead.pohead_id AS orderhead_id
     ,'PO'::text AS orderhead_type
     , pohead.pohead_number AS orderhead_number
     , pohead.pohead_status AS orderhead_status
     , pohead.pohead_orderdate AS orderhead_orderdate
     , (
      SELECT count
           (*) AS count 
        FROM poitem 
       WHERE (poitem.poitem_pohead_id = pohead.pohead_id)
     ) AS orderhead_linecount
     , pohead.pohead_vend_id AS orderhead_from_id
     , vendinfo.vend_name AS orderhead_from
     , NULL::integer AS orderhead_to_id
     ,''::text AS orderhead_to
     , pohead.pohead_curr_id AS orderhead_curr_id
     , pohead.pohead_agent_username AS orderhead_agent_username
     , pohead.pohead_shipvia AS orderhead_shipvia 
  FROM (pohead 
   LEFT JOIN vendinfo 
          ON (
                 (pohead.pohead_vend_id = vendinfo.vend_id)
           )
     )
UNION ALLSELECT cohead.cohead_id AS orderhead_id
     ,'SO'::text AS orderhead_type
     , cohead.cohead_number AS orderhead_number
     , cohead.cohead_status AS orderhead_status
     , cohead.cohead_orderdate AS orderhead_orderdate
     , (
      SELECT count
           (*) AS count 
        FROM coitem 
       WHERE (coitem.coitem_cohead_id = cohead.cohead_id)
     ) AS orderhead_linecount
     , NULL::unknown AS orderhead_from_id
     ,''::text AS orderhead_from
     , cohead.cohead_cust_id AS orderhead_to_id
     , CASE WHEN 
     (length
           (cohead.cohead_shiptoname) > 0
     ) THEN cohead.cohead_shiptoname ELSE cohead.cohead_billtoname END AS orderhead_to
     , cohead.cohead_curr_id AS orderhead_curr_id
     ,''::text AS orderhead_agent_username
     , cohead.cohead_shipvia AS orderhead_shipvia 
  FROM cohead
) data;

Index - Schema public


View: public.orderitem

Union of all order line items for use by widgets and stored procedures which process multiple types of order

public.orderitem Structure
F-Key Name Type Description
orderitem_id integer
orderitem_orderhead_type text
orderitem_orderhead_id integer
orderitem_linenumber integer
orderitem_status bpchar
orderitem_itemsite_id integer
orderitem_scheddate date
orderitem_qty_ordered numeric(18,6)
orderitem_qty_shipped numeric
orderitem_qty_received numeric
orderitem_qty_uom_id integer
orderitem_qty_invuomratio numeric(20,10)
orderitem_unitcost numeric(16,6)
orderitem_unitcost_curr_id integer
orderitem_freight numeric
orderitem_freight_received numeric
orderitem_freight_curr_id integer
(
SELECT poitem.poitem_id AS orderitem_id
     ,'PO' AS orderitem_orderhead_type
     , poitem.poitem_pohead_id AS orderitem_orderhead_id
     , poitem.poitem_linenumber AS orderitem_linenumber
     , poitem.poitem_status AS orderitem_status
     , poitem.poitem_itemsite_id AS orderitem_itemsite_id
     , poitem.poitem_duedate AS orderitem_scheddate
     , poitem.poitem_qty_ordered AS orderitem_qty_ordered
     , poitem.poitem_qty_returned AS orderitem_qty_shipped
     , poitem.poitem_qty_received AS orderitem_qty_received
     , uom.uom_id AS orderitem_qty_uom_id
     , poitem.poitem_invvenduomratio AS orderitem_qty_invuomratio
     , poitem.poitem_unitprice AS orderitem_unitcost
     , pohead.pohead_curr_id AS orderitem_unitcost_curr_id
     , poitem.poitem_freight AS orderitem_freight
     , poitem.poitem_freight_received AS orderitem_freight_received
     , pohead.pohead_curr_id AS orderitem_freight_curr_id 
  FROM (
           (poitem 
         LEFT JOIN pohead 
                ON (
                       (poitem.poitem_pohead_id = pohead.pohead_id)
                 )
           )
   LEFT JOIN uom 
          ON (
                 (uom.uom_name = poitem.poitem_vend_uom)
           )
     )
UNION ALLSELECT coitem.coitem_id AS orderitem_id
     ,'SO' AS orderitem_orderhead_type
     , coitem.coitem_cohead_id AS orderitem_orderhead_id
     , coitem.coitem_linenumber AS orderitem_linenumber
     , coitem.coitem_status AS orderitem_status
     , coitem.coitem_itemsite_id AS orderitem_itemsite_id
     , coitem.coitem_scheddate AS orderitem_scheddate
     , coitem.coitem_qtyord AS orderitem_qty_ordered
     , coitem.coitem_qtyshipped AS orderitem_qty_shipped
     , coitem.coitem_qtyreturned AS orderitem_qty_received
     , coitem.coitem_qty_uom_id AS orderitem_qty_uom_id
     , coitem.coitem_qty_invuomratio AS orderitem_qty_invuomratio
     , coitem.coitem_unitcost AS orderitem_unitcost
     , basecurrid
     () AS orderitem_unitcost_curr_id
     , NULL::unknown AS orderitem_freight
     , NULL::unknown AS orderitem_freight_received
     , basecurrid
     () AS orderitem_freight_curr_id 
  FROM coitem
)
UNION ALLSELECT quitem.quitem_id AS orderitem_id
,'QU' AS orderitem_orderhead_type
, quitem.quitem_quhead_id AS orderitem_orderhead_id
, quitem.quitem_linenumber AS orderitem_linenumber
,'O' AS orderitem_status
, quitem.quitem_itemsite_id AS orderitem_itemsite_id
, quitem.quitem_scheddate AS orderitem_scheddate
, quitem.quitem_qtyord AS orderitem_qty_ordered
, 0 AS orderitem_qty_shipped
, 0 AS orderitem_qty_received
, quitem.quitem_qty_uom_id AS orderitem_qty_uom_id
, quitem.quitem_qty_invuomratio AS orderitem_qty_invuomratio
, quitem.quitem_unitcost AS orderitem_unitcost
, basecurrid
() AS orderitem_unitcost_curr_id
, NULL::unknown AS orderitem_freight
, NULL::unknown AS orderitem_freight_received
, basecurrid
() AS orderitem_freight_curr_id 
FROM quitem;

Index - Schema public


Table: public.orderseq

Configuration information for common numbering sequences

public.orderseq Structure
F-Key Name Type Description
orderseq_id integer PRIMARY KEY DEFAULT nextval(('orderseq_orderseq_id_seq'::text)::regclass)
orderseq_name text UNIQUE NOT NULL
orderseq_number integer
orderseq_table text
orderseq_numcol text
orderseq_seqiss seqiss[]

 

public.orderseq Constraints
Name Constraint
orderseq_orderseq_name_check CHECK ((orderseq_name <> ''::text))

Index - Schema public


Table: public.pack

Temporary table for storing information about Orders added to the Packing List Batch

public.pack Structure
F-Key Name Type Description
pack_id serial PRIMARY KEY
pack_head_id integer NOT NULL
pack_head_type text NOT NULL
public.shiphead.shiphead_id pack_shiphead_id integer
pack_printed boolean NOT NULL DEFAULT false

 

public.pack Constraints
Name Constraint
pack_pack_head_type_check CHECK (((pack_head_type = 'SO'::text) OR (pack_head_type = 'TO'::text)))

Index - Schema public


Table: public.payaropen

Credit Card payment to credit memo join table

public.payaropen Structure
F-Key Name Type Description
payaropen_ccpay_id integer PRIMARY KEY
payaropen_aropen_id integer PRIMARY KEY
payaropen_amount numeric(20,2) NOT NULL DEFAULT 0.00
payaropen_curr_id integer DEFAULT basecurrid()
payaropen_aropen_id_idx payaropen_aropen_id payaropen_ccpay_id_idx payaropen_ccpay_id

Index - Schema public


Table: public.payco

Credit Card payment to sales order join table

public.payco Structure
F-Key Name Type Description
public.ccpay.ccpay_id payco_ccpay_id integer NOT NULL
public.cohead.cohead_id payco_cohead_id integer NOT NULL
payco_amount numeric(20,2) NOT NULL DEFAULT 0.00
payco_curr_id integer DEFAULT basecurrid()
payco_ccpay_id_idx payco_ccpay_id payco_cohead_id_idx payco_cohead_id

Index - Schema public


Table: public.period

Accounting Period information

public.period Structure
F-Key Name Type Description
period_id serial PRIMARY KEY
period_start date
period_end date
period_closed boolean
period_freeze boolean
period_initial boolean DEFAULT false
period_name text
period_yearperiod_id integer
period_quarter integer
period_number integer NOT NULL

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.pkgdep

Package Dependencies list describing which packages are dependent on which other packages.

public.pkgdep Structure
F-Key Name Type Description
pkgdep_id serial PRIMARY KEY
public.pkghead.pkghead_id pkgdep_pkghead_id integer NOT NULL

This is the internal ID of a package which requires at least one other package to be installed first to operate successfully
public.pkghead.pkghead_id pkgdep_parent_pkghead_id integer NOT NULL

This is the internal ID of a package which must be installed for the package pointed to by pkgdep_pkghead_id to operate successfully.

Index - Schema public


Table: public.pkghead

Information about non-core Packages added to the database

public.pkghead Structure
F-Key Name Type Description
pkghead_id serial PRIMARY KEY
pkghead_name text NOT NULL
pkghead_descrip text
pkghead_version text NOT NULL
pkghead_developer text NOT NULL
pkghead_notes text
pkghead_created timestamp with time zone
pkghead_updated timestamp with time zone
pkghead_indev boolean NOT NULL DEFAULT false

Flag indicating whether the contents of this package may be modified in-place - this package is /in dev/elopment.

 

public.pkghead Constraints
Name Constraint
pkghead_pkghead_name_check CHECK ((pkghead_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.pkgitem

Deprecated - the pkgitem table is no longer used to track package contents. It has been replaced by direct queries to the database schema and component tables. This table will be removed when all users have switched to Updater 2.2.0 or later.

public.pkgitem Structure
F-Key Name Type Description
pkgitem_id serial PRIMARY KEY
public.pkghead.pkghead_id pkgitem_pkghead_id integer UNIQUE#1 UNIQUE#2
pkgitem_type text UNIQUE#1 UNIQUE#2
pkgitem_item_id integer UNIQUE#2 NOT NULL
pkgitem_name text UNIQUE#1 NOT NULL
pkgitem_descrip text

 

public.pkgitem Constraints
Name Constraint
pkgitem_pkgitem_type_check CHECK (((((((((((((pkgitem_type = 'C'::text) OR (pkgitem_type = 'D'::text)) OR (pkgitem_type = 'F'::text)) OR (pkgitem_type = 'G'::text)) OR (pkgitem_type = 'I'::text)) OR (pkgitem_type = 'M'::text)) OR (pkgitem_type = 'P'::text)) OR (pkgitem_type = 'R'::text)) OR (pkgitem_type = 'S'::text)) OR (pkgitem_type = 'T'::text)) OR (pkgitem_type = 'U'::text)) OR (pkgitem_type = 'V'::text)))

Index - Schema public


Table: public.plancode

Planner Code information

public.plancode Structure
F-Key Name Type Description
plancode_id integer PRIMARY KEY DEFAULT nextval(('plancode_plancode_id_seq'::text)::regclass)
plancode_code text UNIQUE NOT NULL
plancode_name text
plancode_mpsexplosion character(1)
plancode_consumefcst boolean
plancode_mrpexcp_resched boolean
plancode_mrpexcp_delete boolean

 

public.plancode Constraints
Name Constraint
plancode_plancode_code_check CHECK ((plancode_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.pohead

Purchase Order header information

public.pohead Structure
F-Key Name Type Description
pohead_id integer PRIMARY KEY DEFAULT nextval(('pohead_pohead_id_seq'::text)::regclass)
pohead_status character(1)
pohead_number text UNIQUE NOT NULL
pohead_orderdate date
public.vendinfo.vend_id pohead_vend_id integer
pohead_fob text
pohead_shipvia text
pohead_comments text
pohead_freight numeric(16,2)
pohead_printed boolean DEFAULT false
public.terms.terms_id pohead_terms_id integer
public.whsinfo.warehous_id pohead_warehous_id integer
public.vendaddrinfo.vendaddr_id pohead_vendaddr_id integer
pohead_agent_username text
public.curr_symbol.curr_id pohead_curr_id integer DEFAULT basecurrid()
pohead_saved boolean NOT NULL DEFAULT true
public.taxzone.taxzone_id pohead_taxzone_id integer
public.taxtype.taxtype_id pohead_taxtype_id integer
pohead_dropship boolean DEFAULT false
public.cntct.cntct_id pohead_vend_cntct_id integer
pohead_vend_cntct_honorific text
pohead_vend_cntct_first_name text
pohead_vend_cntct_middle text
pohead_vend_cntct_last_name text
pohead_vend_cntct_suffix text
pohead_vend_cntct_phone text
pohead_vend_cntct_title text
pohead_vend_cntct_fax text
pohead_vend_cntct_email text
pohead_vendaddress1 text
pohead_vendaddress2 text
pohead_vendaddress3 text
pohead_vendcity text
pohead_vendstate text
pohead_vendzipcode text
pohead_vendcountry text
public.cntct.cntct_id pohead_shipto_cntct_id integer
pohead_shipto_cntct_honorific text
pohead_shipto_cntct_first_name text
pohead_shipto_cntct_middle text
pohead_shipto_cntct_last_name text
pohead_shipto_cntct_suffix text
pohead_shipto_cntct_phone text
pohead_shipto_cntct_title text
pohead_shipto_cntct_fax text
pohead_shipto_cntct_email text
public.addr.addr_id pohead_shiptoaddress_id integer
pohead_shiptoaddress1 text
pohead_shiptoaddress2 text
pohead_shiptoaddress3 text
pohead_shiptocity text
pohead_shiptostate text
pohead_shiptozipcode text
pohead_shiptocountry text
public.cohead.cohead_id pohead_cohead_id integer
pohead_released date

 

public.pohead Constraints
Name Constraint
pohead_pohead_number_check CHECK ((pohead_number <> ''::text))
pohead_pohead_status_check CHECK ((((pohead_status = 'U'::bpchar) OR (pohead_status = 'O'::bpchar)) OR (pohead_status = 'C'::bpchar)))
pohead_pohead_status_idx pohead_status

Index - Schema public


Table: public.poitem

Purchase Order Line Item information

public.poitem Structure
F-Key Name Type Description
poitem_id integer PRIMARY KEY DEFAULT nextval(('poitem_poitem_id_seq'::text)::regclass)
poitem_status character(1)
poitem_pohead_id integer UNIQUE#1
poitem_linenumber integer UNIQUE#1
poitem_duedate date
public.itemsite.itemsite_id poitem_itemsite_id integer
poitem_vend_item_descrip text
poitem_vend_uom text
poitem_invvenduomratio numeric(20,10)
poitem_qty_ordered numeric(18,6) NOT NULL
poitem_qty_received numeric(18,6) NOT NULL DEFAULT 0.0
poitem_qty_returned numeric(18,6) NOT NULL DEFAULT 0.0
poitem_qty_vouchered numeric(18,6) NOT NULL DEFAULT 0.0
poitem_unitprice numeric(16,6)
poitem_vend_item_number text
poitem_comments text
poitem_qty_toreceive numeric(18,6)
public.expcat.expcat_id poitem_expcat_id integer
public.itemsrc.itemsrc_id poitem_itemsrc_id integer
poitem_freight numeric(16,4) NOT NULL DEFAULT 0.0
poitem_freight_received numeric(16,4) NOT NULL DEFAULT 0.0
poitem_freight_vouchered numeric(16,4) NOT NULL DEFAULT 0.0
public.prj.prj_id poitem_prj_id integer
poitem_stdcost numeric(16,6)
poitem_bom_rev_id integer
poitem_boo_rev_id integer
poitem_manuf_name text
poitem_manuf_item_number text
poitem_manuf_item_descrip text
public.taxtype.taxtype_id poitem_taxtype_id integer
poitem_tax_recoverable boolean NOT NULL DEFAULT true
poitem_rlsd_duedate date
poitem_order_id integer
poitem_order_type character(1)

 

public.poitem Constraints
Name Constraint
poitem_poitem_status_check CHECK ((((poitem_status = 'U'::bpchar) OR (poitem_status = 'O'::bpchar)) OR (poitem_status = 'C'::bpchar)))
poitem_itemsite_id_key poitem_itemsite_id poitem_itemsite_status_duedate_key poitem_itemsite_id, poitem_status, poitem_duedate poitem_pohead_id_key poitem_pohead_id poitem_status_key poitem_status

Index - Schema public


Table: public.poreject

The poreject table describes Purchase Order Items that were returned to Vendors.

public.poreject Structure
F-Key Name Type Description
poreject_id integer PRIMARY KEY DEFAULT nextval(('"poreject_poreject_id_seq"'::text)::regclass)

This is the internal id of this poreject record
poreject_date timestamp with time zone

This is the date and time the return was entered into the database
poreject_ponumber text

This is the number of the original Purchase Order of this item
poreject_itemsite_id integer

This is the Item Site into which the item had been received
public.vendinfo.vend_id poreject_vend_id integer

This is the Vendor from which the item had been purchased
poreject_vend_item_number text

This is the Vendor's item number for this item
poreject_vend_item_descrip text

This is the Vendor's description of this item
poreject_vend_uom text

This is the Unit of Measure in which the Vendor sold this item
poreject_qty numeric(18,6)

This is the quantity of the item that was returned
poreject_posted boolean

This indicates whether or not the return has been recorded in the General Ledger, Inventory History, and Purchase Order Item
poreject_rjctcode_id integer

This indicates the reason for the return
poreject_poitem_id integer

This is the internal id of the original Purchase Order Item
poreject_invoiced boolean

This indicates whether the Credit Memo associated with the return has been posted
poreject_vohead_id integer

This is the Voucher associated with the Purchase Order Item
poreject_agent_username text

This is the Purchase Order Agent responsible for the original Purchase Order
poreject_voitem_id integer

This is the Voucher Item associated with the Purchase Order Item
poreject_value numeric(18,6)

This is the value (in base currency) of the return at the time it was posted to the General Ledger
poreject_trans_username text

This is the user who recorded the return
public.recv.recv_id poreject_recv_id integer

Index - Schema public


Table: public.potype

Purchase Order Type information

public.potype Structure
F-Key Name Type Description
potype_id serial PRIMARY KEY
potype_name text
potype_descrip text

Index - Schema public


Table: public.pr

Purchase Request information

public.pr Structure
F-Key Name Type Description
pr_id integer PRIMARY KEY DEFAULT nextval(('"pr_pr_id_seq"'::text)::regclass)
pr_number integer
pr_subnumber integer
pr_status character(1)
pr_order_type character(1)
pr_order_id integer
pr_poitem_id integer
pr_duedate date
pr_itemsite_id integer
pr_qtyreq numeric(18,6)
pr_prj_id integer
pr_releasenote text
pr_createdate timestamp without time zone DEFAULT now()

Index - Schema public


Table: public.prftcntr

Profit Center information

public.prftcntr Structure
F-Key Name Type Description
prftcntr_id serial PRIMARY KEY
prftcntr_number text UNIQUE NOT NULL
prftcntr_descrip text

 

public.prftcntr Constraints
Name Constraint
prftcntr_prftcntr_number_check CHECK ((prftcntr_number <> ''::text))

Index - Schema public


Table: public.priv

System Privilege information

public.priv Structure
F-Key Name Type Description
priv_id integer PRIMARY KEY DEFAULT nextval(('priv_priv_id_seq'::text)::regclass)
priv_module text
priv_name text
priv_descrip text
priv_seq integer

Index - Schema public


View: public.privgranted

public.privgranted Structure
F-Key Name Type Description
privilege text
granted boolean
sequence integer
SELECT priv.priv_name AS privilege
, (COALESCE
     (usrpriv.usrpriv_priv_id
           , grppriv.grppriv_priv_id
           , (-1)
     ) > 0
) AS granted
, priv.priv_seq AS sequence 
FROM (
     (priv 
   LEFT JOIN usrpriv 
          ON (
                 (
                       (priv.priv_id = usrpriv.usrpriv_priv_id)
                     AND (usrpriv.usrpriv_username = geteffectivextuser
                             ()
                       )
                 )
           )
     )
LEFT JOIN (
      SELECT DISTINCT grppriv.grppriv_priv_id 
        FROM (grppriv 
              JOIN usrgrp 
                ON (
                       (
                             (grppriv.grppriv_grp_id = usrgrp.usrgrp_grp_id)
                           AND (usrgrp.usrgrp_username = geteffectivextuser
                                   ()
                             )
                       )
                 )
           )
     ) grppriv 
    ON (
           (grppriv.grppriv_priv_id = priv.priv_id)
     )
);

Index - Schema public


Table: public.prj

Project information

public.prj Structure
F-Key Name Type Description
prj_id serial PRIMARY KEY
prj_number text UNIQUE NOT NULL
prj_name text NOT NULL
prj_descrip text
prj_status character(1) NOT NULL
prj_so boolean
prj_wo boolean
prj_po boolean
prj_owner_username text
prj_start_date date
prj_due_date date
prj_assigned_date date
prj_completed_date date
prj_username text
public.prj.prj_id prj_recurring_prj_id integer

The first prj record in the series if this is a recurring Project. If the prj_recurring_prj_id is the same as the prj_id, this record is the first in the series.
public.crmacct.crmacct_id prj_crmacct_id integer
public.cntct.cntct_id prj_cntct_id integer

 

public.prj Constraints
Name Constraint
prj_prj_number_check CHECK ((prj_number <> ''::text))
prj_prj_status_check CHECK ((prj_status = ANY (ARRAY['P'::bpchar, 'O'::bpchar, 'C'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.prjtask

Project Task information

public.prjtask Structure
F-Key Name Type Description
prjtask_id serial PRIMARY KEY
prjtask_number text UNIQUE#1 NOT NULL
prjtask_name text NOT NULL
prjtask_descrip text
public.prj.prj_id prjtask_prj_id integer UNIQUE#1 NOT NULL
prjtask_anyuser boolean
prjtask_status character(1) NOT NULL
prjtask_hours_budget numeric(18,6) NOT NULL
prjtask_hours_actual numeric(18,6) NOT NULL
prjtask_exp_budget numeric(16,4) NOT NULL
prjtask_exp_actual numeric(16,4) NOT NULL
prjtask_owner_username text
prjtask_start_date date
prjtask_due_date date
prjtask_assigned_date date
prjtask_completed_date date
prjtask_username text

 

public.prjtask Constraints
Name Constraint
prjtask_prjtask_status_check CHECK ((prjtask_status = ANY (ARRAY['P'::bpchar, 'O'::bpchar, 'C'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.prjtaskuser

Project Task user information

public.prjtaskuser Structure
F-Key Name Type Description
prjtaskuser_id serial PRIMARY KEY
prjtaskuser_prjtask_id integer
prjtaskuser_username text

Index - Schema public


Table: public.prodcat

Product Category information

public.prodcat Structure
F-Key Name Type Description
prodcat_id integer PRIMARY KEY DEFAULT nextval(('prodcat_prodcat_id_seq'::text)::regclass)
prodcat_code text UNIQUE NOT NULL
prodcat_descrip text

 

public.prodcat Constraints
Name Constraint
prodcat_prodcat_code_check CHECK ((prodcat_code <> ''::text))

Index - Schema public


Table: public.prospect

Prospect Information

public.prospect Structure
F-Key Name Type Description
prospect_id integer PRIMARY KEY DEFAULT nextval('cust_cust_id_seq'::regclass)
prospect_active boolean NOT NULL DEFAULT true
prospect_number text UNIQUE NOT NULL
prospect_name text NOT NULL
public.cntct.cntct_id prospect_cntct_id integer
prospect_comments text
prospect_created date NOT NULL DEFAULT ('now'::text)::date
public.salesrep.salesrep_id prospect_salesrep_id integer
public.whsinfo.warehous_id prospect_warehous_id integer
public.taxzone.taxzone_id prospect_taxzone_id integer

 

public.prospect Constraints
Name Constraint
prospect_prospect_number_check CHECK ((prospect_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.qryhead

A header record for a set of queries to be run sequentially. One use is for data export.

public.qryhead Structure
F-Key Name Type Description
qryhead_id serial PRIMARY KEY

The primary key, holding an internal value used to cross-reference this table.
qryhead_name text UNIQUE NOT NULL

The user-assigned short name for this set of queries.
qryhead_descrip text

A long description of the purpose of this set of queries.
qryhead_notes text

General information about this queryset.
qryhead_username text NOT NULL DEFAULT geteffectivextuser()

The name of the user who last modified this qryhead record.
qryhead_updated date NOT NULL DEFAULT ('now'::text)::date

The date this qryhead was last modified.

 

public.qryhead Constraints
Name Constraint
qryhead_qryhead_name_check CHECK ((qryhead_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.qryitem

The description of a query to be run as part of a set (see qryhead).

public.qryitem Structure
F-Key Name Type Description
qryitem_id serial NOT NULL

The primary key, holding an internal value used to cross-reference this table.
public.qryhead.qryhead_id qryitem_qryhead_id integer UNIQUE#1 UNIQUE#2 NOT NULL

The primary key of the query set to which this individual query belongs.
qryitem_name text UNIQUE#1 NOT NULL
qryitem_order integer UNIQUE#2 NOT NULL

The order in which query items within a query set should be run.
qryitem_src text NOT NULL

The source of the query. If the qryitem_src is "REL" then the qryitem_group and _detail name a particular table or view and all rows will be returned. If the source is "MQL" then the qryitem_group and _detail name a pre-defined MetaSQL query in the metasql table. If the source is "CUSTOM" then the qryitem_detail contains the full MetaSQL text of the query to run.
qryitem_group text

Information to help find the query to run. If the qryitem_src is "REL" then this is the schema in which to find the table or view to query and all rows will be returned (the qryitem_detail names the table or view). If the qryitem_src is "MQL" then this is the group of the query in the metasql table to run (the name is in qryitem_detail). If the qryitem_src IS "CUSTOM" then this ignored.
qryitem_detail text NOT NULL

The particular query to run. If the qryitem_src is "REL" then this is the name of the table or view to query and all rows will be returned. If the qryitem_src is "MQL" then this is the name of the query in the metasql table to run. If the qryitem_src IS "CUSTOM" then this is the actual MetaSQL query text to be parsed and run.
qryitem_notes text NOT NULL DEFAULT ''::text

General information about this query.
qryitem_username text NOT NULL DEFAULT geteffectivextuser()

The name of the user who last modified this qryitem record.
qryitem_updated date NOT NULL DEFAULT ('now'::text)::date

The date this qryitem was last modified.

 

public.qryitem Constraints
Name Constraint
qryitem_qryitem_detail_check CHECK ((btrim(qryitem_detail) <> ''::text))
qryitem_qryitem_src_check CHECK ((qryitem_src = ANY (ARRAY['REL'::text, 'MQL'::text, 'CUSTOM'::text])))

Index - Schema public


Table: public.quhead

Quote header information

public.quhead Structure
F-Key Name Type Description
quhead_id integer PRIMARY KEY DEFAULT nextval(('"quhead_quhead_id_seq"'::text)::regclass)
quhead_number text UNIQUE NOT NULL
quhead_cust_id integer NOT NULL
quhead_quotedate date
public.shiptoinfo.shipto_id quhead_shipto_id integer
quhead_shiptoname text
quhead_shiptoaddress1 text
quhead_shiptoaddress2 text
quhead_shiptoaddress3 text
quhead_shiptocity text
quhead_shiptostate text
quhead_shiptozipcode text
quhead_shiptophone text
public.salesrep.salesrep_id quhead_salesrep_id integer
public.terms.terms_id quhead_terms_id integer
quhead_origin character(1)
quhead_freight numeric(16,4)
quhead_ordercomments text
quhead_shipcomments text
quhead_billtoname text
quhead_billtoaddress1 text
quhead_billtoaddress2 text
quhead_billtoaddress3 text
quhead_billtocity text
quhead_billtostate text
quhead_billtozip text
quhead_commission numeric(16,4)
quhead_custponumber text
quhead_fob text
quhead_shipvia text
public.whsinfo.warehous_id quhead_warehous_id integer
quhead_packdate date
public.prj.prj_id quhead_prj_id integer
quhead_misc numeric(16,4) NOT NULL
public.accnt.accnt_id quhead_misc_accnt_id integer
quhead_misc_descrip text
quhead_billtocountry text
quhead_shiptocountry text
public.curr_symbol.curr_id quhead_curr_id integer DEFAULT basecurrid()
quhead_imported boolean DEFAULT false
quhead_expire date
quhead_calcfreight boolean NOT NULL DEFAULT false
public.cntct.cntct_id quhead_shipto_cntct_id integer
quhead_shipto_cntct_honorific text
quhead_shipto_cntct_first_name text
quhead_shipto_cntct_middle text
quhead_shipto_cntct_last_name text
quhead_shipto_cntct_suffix text
quhead_shipto_cntct_phone text
quhead_shipto_cntct_title text
quhead_shipto_cntct_fax text
quhead_shipto_cntct_email text
public.cntct.cntct_id quhead_billto_cntct_id integer
quhead_billto_cntct_honorific text
quhead_billto_cntct_first_name text
quhead_billto_cntct_middle text
quhead_billto_cntct_last_name text
quhead_billto_cntct_suffix text
quhead_billto_cntct_phone text
quhead_billto_cntct_title text
quhead_billto_cntct_fax text
quhead_billto_cntct_email text
public.taxzone.taxzone_id quhead_taxzone_id integer
public.taxtype.taxtype_id quhead_taxtype_id integer
public.ophead.ophead_id quhead_ophead_id integer
quhead_status text
public.saletype.saletype_id quhead_saletype_id integer

Associated sale type for quote.
public.shipzone.shipzone_id quhead_shipzone_id integer

Associated shipping zone for quote.

 

public.quhead Constraints
Name Constraint
quhead_check CHECK ((((quhead_misc = (0)::numeric) AND (quhead_misc_accnt_id IS NULL)) OR ((quhead_misc <> (0)::numeric) AND (quhead_misc_accnt_id IS NOT NULL))))
quhead_quhead_number_check CHECK ((quhead_number <> ''::text))
quhead_quhead_status_check CHECK ((((quhead_status = 'O'::text) OR (quhead_status = 'C'::text)) OR (quhead_status = 'X'::text)))

Index - Schema public


Table: public.quitem

Quote Line Item information

public.quitem Structure
F-Key Name Type Description
quitem_id integer PRIMARY KEY DEFAULT nextval(('"quitem_quitem_id_seq"'::text)::regclass)
quitem_quhead_id integer
quitem_linenumber integer
quitem_itemsite_id integer
quitem_scheddate date
quitem_qtyord numeric(18,6)
quitem_unitcost numeric(16,6)
quitem_price numeric(16,4)
quitem_custprice numeric(16,4)
quitem_memo text
quitem_custpn text
quitem_createorder boolean
quitem_order_warehous_id integer
quitem_item_id integer
quitem_prcost numeric(16,6)
quitem_imported boolean DEFAULT false
public.uom.uom_id quitem_qty_uom_id integer NOT NULL
quitem_qty_invuomratio numeric(20,10) NOT NULL
public.uom.uom_id quitem_price_uom_id integer NOT NULL
quitem_price_invuomratio numeric(20,10) NOT NULL
quitem_promdate date
public.taxtype.taxtype_id quitem_taxtype_id integer
quitem_dropship boolean DEFAULT false
public.itemsrc.itemsrc_id quitem_itemsrc_id integer
quitem_pricemode character(1) NOT NULL DEFAULT 'D'::bpchar

Pricing mode for quote item. Valid values are D-discount, and M-markup

 

public.quitem Constraints
Name Constraint
valid_quitem_pricemode CHECK ((quitem_pricemode = ANY (ARRAY['D'::bpchar, 'M'::bpchar])))
quitem_quhead_id_key quitem_quhead_id

Index - Schema public


Table: public.rcalitem

Relative Calendar Item information

public.rcalitem Structure
F-Key Name Type Description
rcalitem_id integer PRIMARY KEY DEFAULT nextval(('"xcalitem_xcalitem_id_seq"'::text)::regclass)
rcalitem_calhead_id integer
rcalitem_offsettype character(1)
rcalitem_offsetcount integer
rcalitem_periodtype character(1)
rcalitem_periodcount integer
rcalitem_name text

Index - Schema public


Table: public.recur

Track recurring events and objects.

public.recur Structure
F-Key Name Type Description
recur_id serial PRIMARY KEY

Internal ID of this recurrence record.
recur_parent_id integer UNIQUE#1 NOT NULL

The internal ID of the event/object that recurs.
recur_parent_type text UNIQUE#1 NOT NULL

The table in which the parent event or object is stored.
recur_period text NOT NULL

With recur_freq, how often this event recurs. Values are "m" for every minute, "H" for every hour, "D" for daily, "W" for weekly, "M" for monthly, "Y" for yearly, and "C" for customized or complex.
recur_freq integer NOT NULL DEFAULT 1

With recur_period, how often this event recurs. Values are integers counts of recur_periods. For example, if recur_freq = 2 and recur_period = w then the event recurs every 2 weeks.
recur_start timestamp with time zone DEFAULT now()

The first date/time when the event should occur.
recur_end timestamp with time zone

The last date/time when the event should occur. NULL means there is no end date/time and the event should recur forever.
recur_max integer

The maximum number of recurrence events to create at one time. If this is NULL then when new events are created, a system-wide default will limit the number.
recur_data text

Not yet used and format still undetermined. Additional data to describe how to apply the period and frequency, particularly when period = "C".

 

public.recur Constraints
Name Constraint
recur_recur_period_check CHECK ((recur_period = ANY (ARRAY['m'::text, 'H'::text, 'D'::text, 'W'::text, 'M'::text, 'Y'::text, 'C'::text])))

Index - Schema public


Table: public.recurtype

Describes the properties of recurring items/events in way that can be used by stored procedures to maintain the recurrence.

public.recurtype Structure
F-Key Name Type Description
recurtype_id serial PRIMARY KEY

The internal id of this recurrence description.
recurtype_type text UNIQUE NOT NULL

A code value used by the RecurrenceWidget and the code that uses it to describe the item/event that will recur. Examples include "INCDT" for CRM Incidents and "J" for Projects.
recurtype_table text NOT NULL

The table that holds the item/event that will recur.
recurtype_donecheck text NOT NULL

A boolean expression that returns TRUE if an individual item/event record in the recurtype_table has already been completed.
recurtype_schedcol text NOT NULL

The name of the column in the recurtype_table holding the date or timestamp by which the item is scheduled to be completed or at which the event is supposed to occur.
recurtype_limit text

A boolean expression that returns TRUE if the current user should see the row in the recurtype_table. NULL indicates there is no specific limitation. For example, the maintainance of recurring TODO items should restricted to those items belonging to the user unless s/he has been granted the privilege to modify other people's todo lists.
recurtype_copyfunc text NOT NULL

The name of the function to copy an existing item/event record. The copy function is expected to take at least 2 arguments: the id of the item to copy and the new date/timestamp. If the function accepts more than 2, it must be able to accept NULL values for the 3rd and following arguments.
recurtype_copyargs text[] NOT NULL

An abbreviated argument list for the copy function. This is used to determine whether the second argument must be cast to a date or a timestamp, and to figure out how many additional arguments to pass.
recurtype_delfunc text

The name of the function to delete an existing item/event record. The function is expected to take exactly one argument: the id of the item to delete. NULL indicates there is no delete function and that an SQL DELETE statement can be used. In this case, the id column name will be built as the recurtype_table concatenated with the "_id" suffix.

Index - Schema public


Table: public.recv

Information about Received Orders.

public.recv Structure
F-Key Name Type Description
recv_id serial PRIMARY KEY
recv_order_type text NOT NULL
recv_order_number text NOT NULL
recv_orderitem_id integer NOT NULL
recv_agent_username text
public.itemsite.itemsite_id recv_itemsite_id integer
public.vendinfo.vend_id recv_vend_id integer
recv_vend_item_number text
recv_vend_item_descrip text
recv_vend_uom text
recv_purchcost numeric(16,6)
public.curr_symbol.curr_id recv_purchcost_curr_id integer
recv_duedate date
recv_qty numeric(18,6)
recv_recvcost numeric(16,6)
public.curr_symbol.curr_id recv_recvcost_curr_id integer
recv_freight numeric(16,4)
public.curr_symbol.curr_id recv_freight_curr_id integer
recv_date timestamp with time zone
recv_value numeric(18,6)
recv_posted boolean NOT NULL DEFAULT false
recv_invoiced boolean NOT NULL DEFAULT false
public.vohead.vohead_id recv_vohead_id integer
public.voitem.voitem_id recv_voitem_id integer
recv_trans_usr_name text NOT NULL DEFAULT geteffectivextuser()
recv_notes text
recv_gldistdate date
public.recv.recv_id recv_splitfrom_id integer
recv_rlsd_duedate date

 

public.recv Constraints
Name Constraint
recv_recv_order_type_check CHECK ((((recv_order_type = 'PO'::text) OR (recv_order_type = 'RA'::text)) OR (recv_order_type = 'TO'::text)))

Tables referencing this one via Foreign Key Constraints:

recv_ordertypeid_idx recv_order_type, recv_orderitem_id

Index - Schema public


View: public.remitto

public.remitto Structure
F-Key Name Type Description
remitto_name text
remitto_address1 text
remitto_address2 text
remitto_address3 text
remitto_citystatezip text
remitto_country text
remitto_phone text
SELECT (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_name'::text)
) AS remitto_name
, (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_address1'::text)
) AS remitto_address1
, (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_address2'::text)
) AS remitto_address2
, (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_address3'::text)
) AS remitto_address3
, (
     (
           (
                 (
                       (
                        SELECT metric.metric_value 
                          FROM metric 
                         WHERE (metric.metric_name = 'remitto_city'::text)
                       ) || '  '::text
                 ) || 
                 (
                  SELECT metric.metric_value 
                    FROM metric 
                   WHERE (metric.metric_name = 'remitto_state'::text)
                 )
           ) || '  '::text
     ) || 
     (
      SELECT metric.metric_value 
        FROM metric 
       WHERE (metric.metric_name = 'remitto_zipcode'::text)
     )
) AS remitto_citystatezip
, (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_country'::text)
) AS remitto_country
, (
SELECT metric.metric_value 
  FROM metric 
 WHERE (metric.metric_name = 'remitto_phone'::text)
) AS remitto_phone;

Index - Schema public


Table: public.report

Report definition information

public.report Structure
F-Key Name Type Description
report_id integer PRIMARY KEY DEFAULT nextval(('report_report_id_seq'::text)::regclass)
report_name text
report_sys boolean
report_source text
report_descrip text
report_grade integer NOT NULL
report_loaddate timestamp without time zone

Index - Schema public


Table: public.rjctcode

Reject Code information

public.rjctcode Structure
F-Key Name Type Description
rjctcode_id integer PRIMARY KEY DEFAULT nextval(('"rjctcode_rjctcode_id_seq"'::text)::regclass)
rjctcode_code text UNIQUE NOT NULL
rjctcode_descrip text

 

public.rjctcode Constraints
Name Constraint
rjctcode_rjctcode_code_check CHECK ((rjctcode_code <> ''::text))

Index - Schema public


Table: public.rsncode

Debit/Credit Memo Reason Code information

public.rsncode Structure
F-Key Name Type Description
rsncode_id serial PRIMARY KEY
rsncode_code text UNIQUE NOT NULL
rsncode_descrip text
rsncode_doctype text

 

public.rsncode Constraints
Name Constraint
rsncode_rsncode_code_check CHECK ((rsncode_code <> ''::text))

Index - Schema public


Table: public.sale

Sale information

public.sale Structure
F-Key Name Type Description
sale_id integer PRIMARY KEY DEFAULT nextval(('"sale_sale_id_seq"'::text)::regclass)
sale_name text UNIQUE NOT NULL
sale_descrip text
sale_ipshead_id integer
sale_startdate date
sale_enddate date

 

public.sale Constraints
Name Constraint
sale_sale_name_check CHECK ((sale_name <> ''::text))

Index - Schema public


Table: public.salesaccnt

Sales Account assignment information

public.salesaccnt Structure
F-Key Name Type Description
salesaccnt_id integer PRIMARY KEY DEFAULT nextval(('"salesaccnt_salesaccnt_id_seq"'::text)::regclass)
salesaccnt_custtype_id integer
salesaccnt_prodcat_id integer
salesaccnt_warehous_id integer
salesaccnt_sales_accnt_id integer
salesaccnt_credit_accnt_id integer
salesaccnt_cos_accnt_id integer
salesaccnt_custtype text
salesaccnt_prodcat text
salesaccnt_returns_accnt_id integer
salesaccnt_cor_accnt_id integer
salesaccnt_cow_accnt_id integer
salesaccnt_saletype_id integer

Associated sale type for sales account.
salesaccnt_shipzone_id integer

Associated shipping zone for sales account.
salesaccnt_prodcat_id_idx salesaccnt_prodcat_id salesaccnt_warehous_id_idx salesaccnt_warehous_id

Index - Schema public


Table: public.salescat

Sales Category information

public.salescat Structure
F-Key Name Type Description
salescat_id serial PRIMARY KEY
salescat_active boolean
salescat_name text UNIQUE NOT NULL
salescat_descrip text
salescat_sales_accnt_id integer
salescat_prepaid_accnt_id integer
salescat_ar_accnt_id integer

 

public.salescat Constraints
Name Constraint
salescat_salescat_name_check CHECK ((salescat_name <> ''::text))

Index - Schema public


View: public.saleshistory

Single point for sales history calculations.

public.saleshistory Structure
F-Key Name Type Description
cohist_id integer
cohist_cust_id integer
cohist_itemsite_id integer
cohist_shipdate date
cohist_shipvia text
cohist_ordernumber text
cohist_orderdate date
cohist_invcnumber text
cohist_invcdate date
cohist_qtyshipped numeric(18,6)
cohist_unitprice numeric(16,4)
cohist_shipto_id integer
cohist_salesrep_id integer
cohist_duedate date
cohist_imported boolean
cohist_billtoname text
cohist_billtoaddress1 text
cohist_billtoaddress2 text
cohist_billtoaddress3 text
cohist_billtocity text
cohist_billtostate text
cohist_billtozip text
cohist_shiptoname text
cohist_shiptoaddress1 text
cohist_shiptoaddress2 text
cohist_shiptoaddress3 text
cohist_shiptocity text
cohist_shiptostate text
cohist_shiptozip text
cohist_commission numeric(16,4)
cohist_commissionpaid boolean
cohist_unitcost numeric(18,6)
cohist_misc_type character(1)
cohist_misc_descrip text
cohist_misc_id integer
cohist_doctype text
cohist_promisedate date
cohist_ponumber text
cohist_curr_id integer
cohist_sequence integer
cohist_taxtype_id integer
cohist_taxzone_id integer
cohist_cohead_ccpay_id integer
cohist_saletype_id integer
cohist_shipzone_id integer
invoicenumber text
cust_id integer
cust_number text
cust_name text
cust_curr_id integer
cust_custtype_id integer
custtype_code text
custtype_descrip text
salesrep_number text
salesrep_name text
shipzone_id integer
shipzone_name text
shipzone_descrip text
itemsite_warehous_id integer
itemsite_item_id integer
item_id integer
item_number text
item_descrip1 text
itemdescription text
item_prodcat_id integer
warehous_code text
warehous_descrip text
prodcat_code text
basecommission numeric
baseunitprice numeric
custunitprice numeric
extprice numeric
baseextprice numeric
custextprice numeric
extcost numeric
currabbr character varying
cohist_invcdate_xtnullrole text
cohist_qtyshipped_xtnumericrole text
cohist_unitprice_xtnumericrole text
baseunitprice_xtnumericrole text
custunitprice_xtnumericrole text
custextprice_xtnumericrole text
extprice_xtnumericrole text
baseextprice_xtnumericrole text
cohist_unitcost_xtnumericrole text
extcost_xtnumericrole text
cohist_commission_xtnumericrole text
basecommission_xtnumericrole text
cohist_qtyshipped_xttotalrole integer
custextprice_xttotalrole integer
baseextprice_xttotalrole integer
extcost_xttotalrole integer
basecommission_xttotalrole integer
SELECT cohist.cohist_id
, cohist.cohist_cust_id
, cohist.cohist_itemsite_id
, cohist.cohist_shipdate
, cohist.cohist_shipvia
, cohist.cohist_ordernumber
, cohist.cohist_orderdate
, cohist.cohist_invcnumber
, cohist.cohist_invcdate
, cohist.cohist_qtyshipped
, cohist.cohist_unitprice
, cohist.cohist_shipto_id
, cohist.cohist_salesrep_id
, cohist.cohist_duedate
, cohist.cohist_imported
, cohist.cohist_billtoname
, cohist.cohist_billtoaddress1
, cohist.cohist_billtoaddress2
, cohist.cohist_billtoaddress3
, cohist.cohist_billtocity
, cohist.cohist_billtostate
, cohist.cohist_billtozip
, cohist.cohist_shiptoname
, cohist.cohist_shiptoaddress1
, cohist.cohist_shiptoaddress2
, cohist.cohist_shiptoaddress3
, cohist.cohist_shiptocity
, cohist.cohist_shiptostate
, cohist.cohist_shiptozip
, cohist.cohist_commission
, cohist.cohist_commissionpaid
, cohist.cohist_unitcost
, cohist.cohist_misc_type
, cohist.cohist_misc_descrip
, cohist.cohist_misc_id
, cohist.cohist_doctype
, cohist.cohist_promisedate
, cohist.cohist_ponumber
, cohist.cohist_curr_id
, cohist.cohist_sequence
, cohist.cohist_taxtype_id
, cohist.cohist_taxzone_id
, cohist.cohist_cohead_ccpay_id
, cohist.cohist_saletype_id
, cohist.cohist_shipzone_id
, CASE WHEN 
(cohist.cohist_invcnumber = '-1'::text) THEN 'Credit'::text ELSE cohist.cohist_invcnumber END AS invoicenumber
, custinfo.cust_id
, custinfo.cust_number
, custinfo.cust_name
, custinfo.cust_curr_id
, custinfo.cust_custtype_id
, custtype.custtype_code
, custtype.custtype_descrip
, salesrep.salesrep_number
, salesrep.salesrep_name
, shipzone.shipzone_id
, shipzone.shipzone_name
, shipzone.shipzone_descrip
, itemsite.itemsite_warehous_id
, itemsite.itemsite_item_id
, item.item_id
, item.item_number
, item.item_descrip1
, (
     (item.item_descrip1 || ' '::text) || item.item_descrip2
) AS itemdescription
, item.item_prodcat_id
, site.warehous_code
, site.warehous_descrip
, prodcat.prodcat_code
, currtobase
(cohist.cohist_curr_id
     , cohist.cohist_commission
     , cohist.cohist_invcdate
) AS basecommission
, currtobase
(cohist.cohist_curr_id
     , cohist.cohist_unitprice
     , cohist.cohist_invcdate
) AS baseunitprice
, currtocurr
(cohist.cohist_curr_id
     , custinfo.cust_curr_id
     , cohist.cohist_unitprice
     , cohist.cohist_invcdate
) AS custunitprice
, round
(
     (cohist.cohist_qtyshipped * cohist.cohist_unitprice)
     , 2
) AS extprice
, round
(
     (cohist.cohist_qtyshipped * currtobase
           (cohist.cohist_curr_id
                 , cohist.cohist_unitprice
                 , cohist.cohist_invcdate
           )
     )
     , 2
) AS baseextprice
, round
(
     (cohist.cohist_qtyshipped * currtocurr
           (cohist.cohist_curr_id
                 , custinfo.cust_curr_id
                 , cohist.cohist_unitprice
                 , cohist.cohist_invcdate
           )
     )
     , 2
) AS custextprice
, round
(
     (cohist.cohist_qtyshipped * cohist.cohist_unitcost)
     , 4
) AS extcost
, currconcat
(cohist.cohist_curr_id) AS currabbr
,'Return'::text AS cohist_invcdate_xtnullrole
,'qty'::text AS cohist_qtyshipped_xtnumericrole
,'salesprice'::text AS cohist_unitprice_xtnumericrole
,'salesprice'::text AS baseunitprice_xtnumericrole
,'curr'::text AS custunitprice_xtnumericrole
,'curr'::text AS custextprice_xtnumericrole
,'curr'::text AS extprice_xtnumericrole
,'curr'::text AS baseextprice_xtnumericrole
,'cost'::text AS cohist_unitcost_xtnumericrole
,'curr'::text AS extcost_xtnumericrole
,'curr'::text AS cohist_commission_xtnumericrole
,'curr'::text AS basecommission_xtnumericrole
, 0 AS cohist_qtyshipped_xttotalrole
, 0 AS custextprice_xttotalrole
, 0 AS baseextprice_xttotalrole
, 0 AS extcost_xttotalrole
, 0 AS basecommission_xttotalrole 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (cohist 
                                                  JOIN custinfo 
                                                    ON (
                                                           (custinfo.cust_id = cohist.cohist_cust_id)
                                                     )
                                               )
                                            JOIN custtype 
                                              ON (
                                                     (custtype.custtype_id = custinfo.cust_custtype_id)
                                               )
                                         )
                                      JOIN salesrep 
                                        ON (
                                               (salesrep.salesrep_id = cohist.cohist_salesrep_id)
                                         )
                                   )
                                JOIN itemsite 
                                  ON (
                                         (itemsite.itemsite_id = cohist.cohist_itemsite_id)
                                   )
                             )
                          JOIN site
                             () site
                             (warehous_id
                                   , warehous_code
                                   , warehous_descrip
                                   , warehous_fob
                                   , warehous_active
                                   , warehous_counttag_prefix
                                   , warehous_counttag_number
                                   , warehous_bol_prefix
                                   , warehous_bol_number
                                   , warehous_shipping
                                   , warehous_useslips
                                   , warehous_usezones
                                   , warehous_aislesize
                                   , warehous_aislealpha
                                   , warehous_racksize
                                   , warehous_rackalpha
                                   , warehous_binsize
                                   , warehous_binalpha
                                   , warehous_locationsize
                                   , warehous_locationalpha
                                   , warehous_enforcearbl
                                   , warehous_default_accnt_id
                                   , warehous_shipping_commission
                                   , warehous_cntct_id
                                   , warehous_addr_id
                                   , warehous_transit
                                   , warehous_shipform_id
                                   , warehous_shipvia_id
                                   , warehous_shipcomments
                                   , warehous_costcat_id
                                   , warehous_sitetype_id
                                   , warehous_taxzone_id
                                   , warehous_sequence
                             )
                            ON (
                                   (site.warehous_id = itemsite.itemsite_warehous_id)
                             )
                       )
                    JOIN item 
                      ON (
                             (item.item_id = itemsite.itemsite_item_id)
                       )
                 )
              JOIN prodcat 
                ON (
                       (prodcat.prodcat_id = item.item_prodcat_id)
                 )
           )
   LEFT JOIN shiptoinfo 
          ON (
                 (shiptoinfo.shipto_id = cohist.cohist_shipto_id)
           )
     )
LEFT JOIN shipzone 
    ON (
           (shipzone.shipzone_id = shiptoinfo.shipto_shipzone_id)
     )
);

Index - Schema public


View: public.saleshistorymisc

Single point for sales history (including misc. items) calculations.

public.saleshistorymisc Structure
F-Key Name Type Description
cohist_id integer
cohist_cust_id integer
cohist_itemsite_id integer
cohist_shipdate date
cohist_shipvia text
cohist_ordernumber text
cohist_orderdate date
cohist_invcnumber text
cohist_invcdate date
cohist_qtyshipped numeric(18,6)
cohist_unitprice numeric(16,4)
cohist_shipto_id integer
cohist_salesrep_id integer
cohist_duedate date
cohist_imported boolean
cohist_billtoname text
cohist_billtoaddress1 text
cohist_billtoaddress2 text
cohist_billtoaddress3 text
cohist_billtocity text
cohist_billtostate text
cohist_billtozip text
cohist_shiptoname text
cohist_shiptoaddress1 text
cohist_shiptoaddress2 text
cohist_shiptoaddress3 text
cohist_shiptocity text
cohist_shiptostate text
cohist_shiptozip text
cohist_commission numeric(16,4)
cohist_commissionpaid boolean
cohist_unitcost numeric(18,6)
cohist_misc_type character(1)
cohist_misc_descrip text
cohist_misc_id integer
cohist_doctype text
cohist_promisedate date
cohist_ponumber text
cohist_curr_id integer
cohist_sequence integer
cohist_taxtype_id integer
cohist_taxzone_id integer
cohist_cohead_ccpay_id integer
cohist_saletype_id integer
cohist_shipzone_id integer
invoicenumber text
cust_id integer
cust_number text
cust_name text
cust_curr_id integer
cust_custtype_id integer
custtype_code text
salesrep_number text
salesrep_name text
shipzone_id integer
shipzone_name text
itemsite_warehous_id integer
itemsite_item_id integer
item_number text
item_descrip1 text
itemdescription text
item_prodcat_id integer
warehous_code text
prodcat_code text
basecommission numeric
baseunitprice numeric
custunitprice numeric
extprice numeric
baseextprice numeric
custextprice numeric
extcost numeric
currabbr character varying
cohist_invcdate_xtnullrole text
cohist_qtyshipped_xtnumericrole text
cohist_unitprice_xtnumericrole text
baseunitprice_xtnumericrole text
custunitprice_xtnumericrole text
custextprice_xtnumericrole text
extprice_xtnumericrole text
baseextprice_xtnumericrole text
cohist_unitcost_xtnumericrole text
extcost_xtnumericrole text
cohist_commission_xtnumericrole text
basecommission_xtnumericrole text
cohist_qtyshipped_xttotalrole integer
custextprice_xttotalrole integer
baseextprice_xttotalrole integer
extcost_xttotalrole integer
basecommission_xttotalrole integer
SELECT cohist.cohist_id
, cohist.cohist_cust_id
, cohist.cohist_itemsite_id
, cohist.cohist_shipdate
, cohist.cohist_shipvia
, cohist.cohist_ordernumber
, cohist.cohist_orderdate
, cohist.cohist_invcnumber
, cohist.cohist_invcdate
, cohist.cohist_qtyshipped
, cohist.cohist_unitprice
, cohist.cohist_shipto_id
, cohist.cohist_salesrep_id
, cohist.cohist_duedate
, cohist.cohist_imported
, cohist.cohist_billtoname
, cohist.cohist_billtoaddress1
, cohist.cohist_billtoaddress2
, cohist.cohist_billtoaddress3
, cohist.cohist_billtocity
, cohist.cohist_billtostate
, cohist.cohist_billtozip
, cohist.cohist_shiptoname
, cohist.cohist_shiptoaddress1
, cohist.cohist_shiptoaddress2
, cohist.cohist_shiptoaddress3
, cohist.cohist_shiptocity
, cohist.cohist_shiptostate
, cohist.cohist_shiptozip
, cohist.cohist_commission
, cohist.cohist_commissionpaid
, cohist.cohist_unitcost
, cohist.cohist_misc_type
, cohist.cohist_misc_descrip
, cohist.cohist_misc_id
, cohist.cohist_doctype
, cohist.cohist_promisedate
, cohist.cohist_ponumber
, cohist.cohist_curr_id
, cohist.cohist_sequence
, cohist.cohist_taxtype_id
, cohist.cohist_taxzone_id
, cohist.cohist_cohead_ccpay_id
, cohist.cohist_saletype_id
, cohist.cohist_shipzone_id
, CASE WHEN 
(cohist.cohist_invcnumber = '-1'::text) THEN 'Credit'::text ELSE cohist.cohist_invcnumber END AS invoicenumber
, custinfo.cust_id
, custinfo.cust_number
, custinfo.cust_name
, custinfo.cust_curr_id
, custinfo.cust_custtype_id
, custtype.custtype_code
, salesrep.salesrep_number
, salesrep.salesrep_name
, shipzone.shipzone_id
, shipzone.shipzone_name
, itemsite.itemsite_warehous_id
, itemsite.itemsite_item_id
, item.item_number
, item.item_descrip1
, (
     (item.item_descrip1 || ' '::text) || item.item_descrip2
) AS itemdescription
, item.item_prodcat_id
, site.warehous_code
, prodcat.prodcat_code
, currtobase
(cohist.cohist_curr_id
     , cohist.cohist_commission
     , cohist.cohist_invcdate
) AS basecommission
, currtobase
(cohist.cohist_curr_id
     , cohist.cohist_unitprice
     , cohist.cohist_invcdate
) AS baseunitprice
, currtocurr
(cohist.cohist_curr_id
     , custinfo.cust_curr_id
     , cohist.cohist_unitprice
     , cohist.cohist_invcdate
) AS custunitprice
, round
(
     (cohist.cohist_qtyshipped * cohist.cohist_unitprice)
     , 2
) AS extprice
, round
(
     (cohist.cohist_qtyshipped * currtobase
           (cohist.cohist_curr_id
                 , cohist.cohist_unitprice
                 , cohist.cohist_invcdate
           )
     )
     , 2
) AS baseextprice
, round
(
     (cohist.cohist_qtyshipped * currtocurr
           (cohist.cohist_curr_id
                 , custinfo.cust_curr_id
                 , cohist.cohist_unitprice
                 , cohist.cohist_invcdate
           )
     )
     , 2
) AS custextprice
, round
(
     (cohist.cohist_qtyshipped * cohist.cohist_unitcost)
     , 4
) AS extcost
, currconcat
(cohist.cohist_curr_id) AS currabbr
,'Return'::text AS cohist_invcdate_xtnullrole
,'qty'::text AS cohist_qtyshipped_xtnumericrole
,'salesprice'::text AS cohist_unitprice_xtnumericrole
,'salesprice'::text AS baseunitprice_xtnumericrole
,'curr'::text AS custunitprice_xtnumericrole
,'curr'::text AS custextprice_xtnumericrole
,'curr'::text AS extprice_xtnumericrole
,'curr'::text AS baseextprice_xtnumericrole
,'cost'::text AS cohist_unitcost_xtnumericrole
,'curr'::text AS extcost_xtnumericrole
,'curr'::text AS cohist_commission_xtnumericrole
,'curr'::text AS basecommission_xtnumericrole
, 0 AS cohist_qtyshipped_xttotalrole
, 0 AS custextprice_xttotalrole
, 0 AS baseextprice_xttotalrole
, 0 AS extcost_xttotalrole
, 0 AS basecommission_xttotalrole 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (
                                               (cohist 
                                                  JOIN custinfo 
                                                    ON (
                                                           (custinfo.cust_id = cohist.cohist_cust_id)
                                                     )
                                               )
                                            JOIN custtype 
                                              ON (
                                                     (custtype.custtype_id = custinfo.cust_custtype_id)
                                               )
                                         )
                                      JOIN salesrep 
                                        ON (
                                               (salesrep.salesrep_id = cohist.cohist_salesrep_id)
                                         )
                                   )
                           LEFT JOIN itemsite 
                                  ON (
                                         (itemsite.itemsite_id = cohist.cohist_itemsite_id)
                                   )
                             )
                     LEFT JOIN site
                             () site
                             (warehous_id
                                   , warehous_code
                                   , warehous_descrip
                                   , warehous_fob
                                   , warehous_active
                                   , warehous_counttag_prefix
                                   , warehous_counttag_number
                                   , warehous_bol_prefix
                                   , warehous_bol_number
                                   , warehous_shipping
                                   , warehous_useslips
                                   , warehous_usezones
                                   , warehous_aislesize
                                   , warehous_aislealpha
                                   , warehous_racksize
                                   , warehous_rackalpha
                                   , warehous_binsize
                                   , warehous_binalpha
                                   , warehous_locationsize
                                   , warehous_locationalpha
                                   , warehous_enforcearbl
                                   , warehous_default_accnt_id
                                   , warehous_shipping_commission
                                   , warehous_cntct_id
                                   , warehous_addr_id
                                   , warehous_transit
                                   , warehous_shipform_id
                                   , warehous_shipvia_id
                                   , warehous_shipcomments
                                   , warehous_costcat_id
                                   , warehous_sitetype_id
                                   , warehous_taxzone_id
                                   , warehous_sequence
                             )
                            ON (
                                   (site.warehous_id = itemsite.itemsite_warehous_id)
                             )
                       )
               LEFT JOIN item 
                      ON (
                             (item.item_id = itemsite.itemsite_item_id)
                       )
                 )
         LEFT JOIN prodcat 
                ON (
                       (prodcat.prodcat_id = item.item_prodcat_id)
                 )
           )
   LEFT JOIN shiptoinfo 
          ON (
                 (shiptoinfo.shipto_id = cohist.cohist_shipto_id)
           )
     )
LEFT JOIN shipzone 
    ON (
           (shipzone.shipzone_id = shiptoinfo.shipto_shipzone_id)
     )
);

Index - Schema public


Table: public.salesrep

Sales Representative information

public.salesrep Structure
F-Key Name Type Description
salesrep_id integer PRIMARY KEY DEFAULT nextval(('salesrep_salesrep_id_seq'::text)::regclass)
salesrep_active boolean
salesrep_number text UNIQUE NOT NULL
salesrep_name text
salesrep_commission numeric(8,4)
salesrep_method character(1)
public.emp.emp_id salesrep_emp_id integer

DEPRECATED - the relationship between Sales Rep and Employee is now maintained through the crmacct table.

 

public.salesrep Constraints
Name Constraint
salesrep_salesrep_number_check CHECK ((salesrep_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.saletype

Type or Origination of Sale.

public.saletype Structure
F-Key Name Type Description
saletype_id serial PRIMARY KEY

Sequence identifier for sale type.
saletype_code text NOT NULL

User defined identifier for sale type.
saletype_descr text

Description for sale type.
saletype_active boolean NOT NULL DEFAULT true

Boolean to deactivate a sale type.

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.schemaord

Set the order in which db schemas will appear in the search path after login

public.schemaord Structure
F-Key Name Type Description
schemaord_id serial PRIMARY KEY
schemaord_name text UNIQUE NOT NULL
schemaord_order integer UNIQUE NOT NULL

 

public.schemaord Constraints
Name Constraint
schemaord_schemaord_name_check CHECK ((length(schemaord_name) > 0))
schemaord_schemaord_name_check1 CHECK ((schemaord_name <> ''::text))

Index - Schema public


Table: public.script

public.script Structure
F-Key Name Type Description
script_id serial PRIMARY KEY
script_name text NOT NULL
script_order integer NOT NULL
script_enabled boolean NOT NULL DEFAULT false
script_source text NOT NULL
script_notes text

Index - Schema public


Table: public.sequence

Pre-populated list of sequence numbers (1-1000) used for printing Labels and other uses

public.sequence Structure
F-Key Name Type Description
sequence_value integer

Index - Schema public


Table: public.shift

List of work Shifts

public.shift Structure
F-Key Name Type Description
shift_id serial PRIMARY KEY
shift_number text NOT NULL
shift_name text NOT NULL

 

public.shift Constraints
Name Constraint
shift_shift_number_check CHECK ((shift_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.shipchrg

Shipping Charge information

public.shipchrg Structure
F-Key Name Type Description
shipchrg_id serial PRIMARY KEY
shipchrg_name text NOT NULL
shipchrg_descrip text
shipchrg_custfreight boolean
shipchrg_handling character(1)

 

public.shipchrg Constraints
Name Constraint
shipchrg_shipchrg_name_check CHECK ((shipchrg_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.shipdata

Shipping Interface information - note that the shipdata_cohead_nember is text and not int. That is due to ODBC chopping off during the transfer

public.shipdata Structure
F-Key Name Type Description
shipdata_cohead_number text PRIMARY KEY
shipdata_cosmisc_tracknum text PRIMARY KEY
shipdata_cosmisc_packnum_tracknum text PRIMARY KEY
shipdata_weight numeric(16,4)
shipdata_base_freight numeric(16,4)
shipdata_total_freight numeric(16,4)
shipdata_shipper text DEFAULT 'UPS'::text
shipdata_billing_option text
shipdata_package_type text
shipdata_void_ind character(1) PRIMARY KEY
shipdata_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
public.shiphead.shiphead_number shipdata_shiphead_number text
public.curr_symbol.curr_id shipdata_base_freight_curr_id integer DEFAULT basecurrid()
public.curr_symbol.curr_id shipdata_total_freight_curr_id integer DEFAULT basecurrid()
shipdata_cohead_number_idx shipdata_cohead_number

Index - Schema public


Table: public.shipdatasum

Shipping Interface information.

public.shipdatasum Structure
F-Key Name Type Description
shipdatasum_cohead_number text PRIMARY KEY
shipdatasum_cosmisc_tracknum text PRIMARY KEY
shipdatasum_cosmisc_packnum_tracknum text PRIMARY KEY
shipdatasum_weight numeric(16,4)
shipdatasum_base_freight numeric(16,4)
shipdatasum_total_freight numeric(16,4)
shipdatasum_shipper text DEFAULT 'UPS'::text
shipdatasum_billing_option text
shipdatasum_package_type text
shipdatasum_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
shipdatasum_shipped boolean DEFAULT false
public.shiphead.shiphead_number shipdatasum_shiphead_number text
public.curr_symbol.curr_id shipdatasum_base_freight_curr_id integer DEFAULT basecurrid()
public.curr_symbol.curr_id shipdatasum_total_freight_curr_id integer DEFAULT basecurrid()
shipdatasum_cohead_number_idx shipdatasum_cohead_number shipdatasum_cosmisc_tracknum_idx shipdatasum_cosmisc_tracknum

Index - Schema public


Table: public.shipform

Shipping Form information

public.shipform Structure
F-Key Name Type Description
shipform_id integer PRIMARY KEY DEFAULT nextval(('"shipform_shipform_id_seq"'::text)::regclass)
shipform_name text UNIQUE NOT NULL
shipform_report_id integer

Obsolete -- reference shipform_report_name instead.
shipform_report_name text

 

public.shipform Constraints
Name Constraint
shipform_shipform_name_check CHECK ((shipform_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.shiphead

General information about Shipments

public.shiphead Structure
F-Key Name Type Description
shiphead_id serial PRIMARY KEY
shiphead_order_id integer NOT NULL
shiphead_order_type text NOT NULL
shiphead_number text UNIQUE NOT NULL
shiphead_shipvia text
shiphead_freight numeric(16,4) NOT NULL DEFAULT 0.0
public.curr_symbol.curr_id shiphead_freight_curr_id integer NOT NULL DEFAULT basecurrid()
shiphead_notes text
shiphead_shipped boolean NOT NULL DEFAULT false
shiphead_shipdate date
public.shipchrg.shipchrg_id shiphead_shipchrg_id integer
public.shipform.shipform_id shiphead_shipform_id integer
shiphead_sfstatus character(1) NOT NULL
shiphead_tracknum text

 

public.shiphead Constraints
Name Constraint
shiphead_shiphead_number_check CHECK ((shiphead_number <> ''::text))
shiphead_shiphead_order_type_check CHECK (((shiphead_order_type = 'SO'::text) OR (shiphead_order_type = 'TO'::text)))
shiphead_shiphead_sfstatus_check CHECK ((((shiphead_sfstatus = 'D'::bpchar) OR (shiphead_sfstatus = 'N'::bpchar)) OR (shiphead_sfstatus = 'P'::bpchar)))

Tables referencing this one via Foreign Key Constraints:

shiphead_order_id_idx shiphead_order_id shiphead_shipped_idx shiphead_shipped

Index - Schema public


Table: public.shipitem

Information about Shipment Line Items

public.shipitem Structure
F-Key Name Type Description
shipitem_id serial PRIMARY KEY
shipitem_orderitem_id integer NOT NULL
public.shiphead.shiphead_id shipitem_shiphead_id integer NOT NULL
shipitem_qty numeric(18,6) NOT NULL
shipitem_shipped boolean NOT NULL DEFAULT false
shipitem_shipdate timestamp with time zone
shipitem_transdate timestamp with time zone
shipitem_trans_username text
shipitem_invoiced boolean NOT NULL DEFAULT false
public.invcitem.invcitem_id shipitem_invcitem_id integer
shipitem_value numeric(18,6)
public.invhist.invhist_id shipitem_invhist_id integer
shipitem_invcitem_id_idx shipitem_invcitem_id shipitem_orderitem_id_idx shipitem_orderitem_id shipitem_shiphead_id_idx shipitem_shiphead_id

Index - Schema public


Table: public.shiptoinfo

Ship-To information

public.shiptoinfo Structure
F-Key Name Type Description
shipto_id integer PRIMARY KEY DEFAULT nextval(('shipto_shipto_id_seq'::text)::regclass)
public.custinfo.cust_id shipto_cust_id integer UNIQUE#1 NOT NULL
shipto_name text
public.salesrep.salesrep_id public.salesrep.salesrep_id shipto_salesrep_id integer
shipto_comments text
shipto_shipcomments text
public.shipzone.shipzone_id shipto_shipzone_id integer
shipto_shipvia text
shipto_commission numeric(10,4) NOT NULL
public.shipform.shipform_id public.shipform.shipform_id shipto_shipform_id integer
shipto_shipchrg_id integer
shipto_active boolean NOT NULL
shipto_default boolean
shipto_num text UNIQUE#1
shipto_ediprofile_id integer

Deprecated column - DO NOT USE
public.cntct.cntct_id shipto_cntct_id integer
public.addr.addr_id shipto_addr_id integer
public.taxzone.taxzone_id shipto_taxzone_id integer

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.shipvia

Ship Via information

public.shipvia Structure
F-Key Name Type Description
shipvia_id integer PRIMARY KEY DEFAULT nextval(('shipvia_shipvia_id_seq'::text)::regclass)
shipvia_code text UNIQUE NOT NULL
shipvia_descrip text

 

public.shipvia Constraints
Name Constraint
shipvia_shipvia_code_check CHECK ((shipvia_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.shipzone

Shipping Zone information

public.shipzone Structure
F-Key Name Type Description
shipzone_id integer PRIMARY KEY DEFAULT nextval(('shipzone_shipzone_id_seq'::text)::regclass)
shipzone_name text UNIQUE NOT NULL
shipzone_descrip text

 

public.shipzone Constraints
Name Constraint
shipzone_shipzone_name_check CHECK ((shipzone_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.sitetype

This table is the different types of sites.

public.sitetype Structure
F-Key Name Type Description
sitetype_id serial PRIMARY KEY
sitetype_name text UNIQUE NOT NULL
sitetype_descrip text

 

public.sitetype Constraints
Name Constraint
sitetype_sitetype_name_check CHECK ((sitetype_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.sltrans

Journal transaction information

public.sltrans Structure
F-Key Name Type Description
sltrans_id integer PRIMARY KEY DEFAULT nextval('gltrans_gltrans_id_seq'::regclass)
sltrans_created timestamp with time zone
sltrans_date date NOT NULL
sltrans_sequence integer
sltrans_accnt_id integer NOT NULL
sltrans_source text
sltrans_docnumber text
sltrans_misc_id integer
sltrans_amount numeric(20,2) NOT NULL
sltrans_notes text
sltrans_journalnumber integer
sltrans_posted boolean NOT NULL
sltrans_doctype text
sltrans_username text NOT NULL DEFAULT geteffectivextuser()
sltrans_gltrans_journalnumber integer
sltrans_rec boolean NOT NULL DEFAULT false
sltrans_sequence_idx sltrans_sequence sltrans_sltrans_accnt_id_idx sltrans_accnt_id sltrans_sltrans_date_idx sltrans_date sltrans_sltrans_journalnumber_idx sltrans_journalnumber

Index - Schema public


Table: public.sltrans_backup

backup cross references of old and new ids for sltrans 4.0 upgrade.

public.sltrans_backup Structure
F-Key Name Type Description
sltrans_old_id integer
sltrans_new_id integer

Index - Schema public


Table: public.source

Tax class information

public.source Structure
F-Key Name Type Description
source_id serial PRIMARY KEY

Primary key
source_module text

Application module
source_name text UNIQUE NOT NULL

Name
source_descrip text

Description

 

public.source Constraints
Name Constraint
source_source_name_check CHECK ((source_name <> ''::text))

Index - Schema public


Table: public.state

List of states, provinces, and territories associated with various countries.

public.state Structure
F-Key Name Type Description
state_id serial PRIMARY KEY
state_name text UNIQUE#1 NOT NULL
state_abbr text
public.country.country_id state_country_id integer UNIQUE#1

 

public.state Constraints
Name Constraint
state_state_name_check CHECK ((state_name <> ''::text))

Index - Schema public


Table: public.status

public.status Structure
F-Key Name Type Description
status_id serial PRIMARY KEY
status_type text UNIQUE#1 NOT NULL
status_code character(1) UNIQUE#1 NOT NULL
status_name text
status_seq integer
status_color text DEFAULT 'white'::text

Index - Schema public


Table: public.stdjrnl

Standard Journal information

public.stdjrnl Structure
F-Key Name Type Description
stdjrnl_id serial PRIMARY KEY
stdjrnl_name text UNIQUE NOT NULL
stdjrnl_descrip text
stdjrnl_notes text

 

public.stdjrnl Constraints
Name Constraint
stdjrnl_stdjrnl_name_check CHECK ((stdjrnl_name <> ''::text))

Index - Schema public


Table: public.stdjrnlgrp

Standard Journal Group information

public.stdjrnlgrp Structure
F-Key Name Type Description
stdjrnlgrp_id serial PRIMARY KEY
stdjrnlgrp_name text UNIQUE NOT NULL
stdjrnlgrp_descrip text

 

public.stdjrnlgrp Constraints
Name Constraint
stdjrnlgrp_stdjrnlgrp_name_check CHECK ((stdjrnlgrp_name <> ''::text))

Index - Schema public


Table: public.stdjrnlgrpitem

Standard Journal Group Item information

public.stdjrnlgrpitem Structure
F-Key Name Type Description
stdjrnlgrpitem_id serial PRIMARY KEY
stdjrnlgrpitem_stdjrnl_id integer
stdjrnlgrpitem_toapply integer
stdjrnlgrpitem_applied integer
stdjrnlgrpitem_effective date
stdjrnlgrpitem_expires date
stdjrnlgrpitem_stdjrnlgrp_id integer

Index - Schema public


Table: public.stdjrnlitem

Standard Journal Item information

public.stdjrnlitem Structure
F-Key Name Type Description
stdjrnlitem_id serial PRIMARY KEY
stdjrnlitem_stdjrnl_id integer NOT NULL
stdjrnlitem_accnt_id integer NOT NULL
stdjrnlitem_amount numeric(20,2) NOT NULL
stdjrnlitem_notes text

Index - Schema public


Table: public.subaccnt

Subaccount information

public.subaccnt Structure
F-Key Name Type Description
subaccnt_id serial PRIMARY KEY
subaccnt_number text UNIQUE NOT NULL
subaccnt_descrip text

 

public.subaccnt Constraints
Name Constraint
subaccnt_subaccnt_number_check CHECK ((subaccnt_number <> ''::text))

Index - Schema public


Table: public.subaccnttype

User defined Sub Account Types.

public.subaccnttype Structure
F-Key Name Type Description
subaccnttype_id serial PRIMARY KEY
subaccnttype_accnt_type character(1) NOT NULL
subaccnttype_code text NOT NULL
subaccnttype_descrip text

Index - Schema public


Table: public.tax

Tax information

public.tax Structure
F-Key Name Type Description
tax_id integer PRIMARY KEY DEFAULT nextval(('"tax_tax_id_seq"'::text)::regclass)
tax_code text NOT NULL
tax_descrip text
public.accnt.accnt_id tax_sales_accnt_id integer

Deprecated column - DO NOT USE
public.taxclass.taxclass_id tax_taxclass_id integer
public.taxauth.taxauth_id tax_taxauth_id integer
public.tax.tax_id tax_basis_tax_id integer

 

public.tax Constraints
Name Constraint
tax_tax_code_check CHECK ((tax_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.taxass

The tax assignment table associates different tax zones and tax types to a given set of tax codes.

public.taxass Structure
F-Key Name Type Description
taxass_id serial PRIMARY KEY
public.taxzone.taxzone_id taxass_taxzone_id integer UNIQUE#1

The id of the tax zone. If NULL any tax zone will apply.
public.taxtype.taxtype_id taxass_taxtype_id integer UNIQUE#1

The id of the tax type. If NULL any tax type will apply.
public.tax.tax_id taxass_tax_id integer UNIQUE#1 NOT NULL

The id of the tax code.

Index - Schema public


Table: public.taxauth

The Tax Authority table.

public.taxauth Structure
F-Key Name Type Description
taxauth_id serial PRIMARY KEY
taxauth_code text UNIQUE NOT NULL
taxauth_name text
taxauth_extref text
public.addr.addr_id taxauth_addr_id integer
public.curr_symbol.curr_id taxauth_curr_id integer

The required currency for recording tax information as. NULL means no preference.
taxauth_county text
public.accnt.accnt_id taxauth_accnt_id integer

 

public.taxauth Constraints
Name Constraint
taxauth_taxauth_code_check CHECK ((taxauth_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.taxclass

Tax class information

public.taxclass Structure
F-Key Name Type Description
taxclass_id serial PRIMARY KEY

Primary key
taxclass_code text UNIQUE NOT NULL

Code
taxclass_descrip text

Description
taxclass_sequence integer

Group sequence

 

public.taxclass Constraints
Name Constraint
taxclass_taxclass_code_check CHECK ((taxclass_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.taxhist

A table type to record tax transaction history. Inherited by other tables that actually record history. As the parent, queries can be run against it that will join all child tables.

public.taxhist Structure
F-Key Name Type Description
taxhist_id serial PRIMARY KEY

Primary key
taxhist_parent_id integer NOT NULL

Source parent id.
public.taxtype.taxtype_id taxhist_taxtype_id integer

Tax type id
public.tax.tax_id taxhist_tax_id integer NOT NULL

Tax code id.
taxhist_basis numeric(16,2) NOT NULL

Base price amount on which the tax calculation is based.
taxhist_basis_tax_id integer

Tax rate calculation basis. If null, then the amount of the parent document, otherwise calculated on the result amount of the tax code id referenced.
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL

Flat tax amount.
taxhist_tax numeric(16,6) NOT NULL

Calculated tax amount.
taxhist_docdate date NOT NULL

The date of the parent document.
taxhist_distdate date

The G/L distribution date of the parent document.
public.curr_symbol.curr_id taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Index - Schema public


Table: public.taxrate

Tax rates.

public.taxrate Structure
F-Key Name Type Description
taxrate_id serial PRIMARY KEY

Primary key.
public.tax.tax_id taxrate_tax_id integer NOT NULL

The id of the parent tax code.
taxrate_percent numeric(10,6) NOT NULL

Tax rate percentage.
public.curr_symbol.curr_id taxrate_curr_id integer

The currency id of the flat rate amount.
taxrate_amount numeric(16,2) NOT NULL

Flat tax rate amount.
taxrate_effective date

The effective date of the tax rate. NULL value means always.
taxrate_expires date

The expire date of the tax rate. NULL value means never.

Index - Schema public


Table: public.taxreg

Stores Tax Registration numbers related to objects and a given tax authority. The rel_id specifies the object id and teh rel_type specifies the object type. See column comment for additional detail on types.

public.taxreg Structure
F-Key Name Type Description
taxreg_id serial PRIMARY KEY
taxreg_rel_id integer NOT NULL
taxreg_rel_type character(1)

The type of relation this record is for. Known values are C=Customer, V=Vendor, NULL=This Manufacturer in which case taxreg_rel_id is meaningless and should be -1.
public.taxauth.taxauth_id taxreg_taxauth_id integer
taxreg_number text NOT NULL
public.taxzone.taxzone_id taxreg_taxzone_id integer
taxreg_effective date DEFAULT startoftime()
taxreg_expires date DEFAULT endoftime()
taxreg_notes text DEFAULT ''::text

 

public.taxreg Constraints
Name Constraint
taxreg_taxreg_number_check CHECK ((taxreg_number <> ''::text))

Index - Schema public


Table: public.taxtype

The list of Tax Types

public.taxtype Structure
F-Key Name Type Description
taxtype_id serial PRIMARY KEY
taxtype_name text UNIQUE NOT NULL
taxtype_descrip text
taxtype_sys boolean NOT NULL DEFAULT false

 

public.taxtype Constraints
Name Constraint
taxtype_taxtype_name_check CHECK ((taxtype_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.taxzone

Tax zone information

public.taxzone Structure
F-Key Name Type Description
taxzone_id serial PRIMARY KEY

Primary key
taxzone_code text UNIQUE NOT NULL

Code
taxzone_descrip text

Description

 

public.taxzone Constraints
Name Constraint
taxzone_taxzone_code_check CHECK ((taxzone_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.terms

Billing Terms information

public.terms Structure
F-Key Name Type Description
terms_id integer PRIMARY KEY DEFAULT nextval(('terms_terms_id_seq'::text)::regclass)
terms_code text UNIQUE NOT NULL
terms_descrip text
terms_type character(1)
terms_duedays integer
terms_discdays integer
terms_discprcnt numeric(10,6)
terms_cutoffday integer
terms_ap boolean
terms_ar boolean

 

public.terms Constraints
Name Constraint
terms_terms_code_check CHECK ((terms_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.todoitem

To-Do List items.

public.todoitem Structure
F-Key Name Type Description
todoitem_id serial PRIMARY KEY
todoitem_name text NOT NULL
todoitem_description text
public.incdt.incdt_id todoitem_incdt_id integer
todoitem_creator_username text NOT NULL DEFAULT geteffectivextuser()
todoitem_status character(1)
todoitem_active boolean NOT NULL DEFAULT true
todoitem_start_date date
todoitem_due_date date
todoitem_assigned_date date
todoitem_completed_date date
todoitem_seq integer NOT NULL
todoitem_notes text
public.crmacct.crmacct_id todoitem_crmacct_id integer
public.ophead.ophead_id todoitem_ophead_id integer
todoitem_owner_username text
todoitem_priority_id integer
todoitem_username text
public.todoitem.todoitem_id todoitem_recurring_todoitem_id integer

The first todoitem record in the series if this is a recurring To-Do item. If the todoitem_recurring_todoitem_id is the same as the todoitem_id, this record is the first in the series.
public.cntct.cntct_id todoitem_cntct_id integer

Tables referencing this one via Foreign Key Constraints:

todoitem_todoitem_username_idx todoitem_username

Index - Schema public


Table: public.trgthist

public.trgthist Structure
F-Key Name Type Description
public.cntctmrgd.cntctmrgd_cntct_id trgthist_src_cntct_id integer NOT NULL
public.cntct.cntct_id trgthist_trgt_cntct_id integer NOT NULL
trgthist_col text NOT NULL
trgthist_value text NOT NULL

Index - Schema public


Table: public.trialbal

Trial Balance information

public.trialbal Structure
F-Key Name Type Description
trialbal_id serial PRIMARY KEY
trialbal_period_id integer
trialbal_accnt_id integer
trialbal_beginning numeric(20,2)
trialbal_ending numeric(20,2)
trialbal_credits numeric(20,2)
trialbal_debits numeric(20,2)
trialbal_dirty boolean
trialbal_yearend numeric(20,2) NOT NULL DEFAULT 0.00

Index - Schema public


Table: public.uiform

public.uiform Structure
F-Key Name Type Description
uiform_id serial PRIMARY KEY
uiform_name text NOT NULL
uiform_order integer NOT NULL
uiform_enabled boolean NOT NULL DEFAULT false
uiform_source text NOT NULL
uiform_notes text

Index - Schema public


Table: public.uom

Unit of Measure information

public.uom Structure
F-Key Name Type Description
uom_id serial PRIMARY KEY
uom_name text UNIQUE NOT NULL
uom_descrip text
uom_item_weight boolean NOT NULL DEFAULT false

 

public.uom Constraints
Name Constraint
uom_uom_name_check CHECK ((uom_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.uomconv

UOM conversion information. From Unit to To Unit with a value per ratio.

public.uomconv Structure
F-Key Name Type Description
uomconv_id serial PRIMARY KEY
public.uom.uom_id uomconv_from_uom_id integer NOT NULL
uomconv_from_value numeric(20,10) NOT NULL
public.uom.uom_id uomconv_to_uom_id integer NOT NULL
uomconv_to_value numeric(20,10) NOT NULL
uomconv_fractional boolean NOT NULL DEFAULT false

Index - Schema public


Table: public.uomtype

UOM Type values.

public.uomtype Structure
F-Key Name Type Description
uomtype_id serial PRIMARY KEY
uomtype_name text UNIQUE NOT NULL
uomtype_descrip text
uomtype_multiple boolean NOT NULL DEFAULT false

 

public.uomtype Constraints
Name Constraint
uomtype_uomtype_name_check CHECK ((uomtype_name <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


View: public.url

public.url Structure
F-Key Name Type Description
url_id integer
url_source_id integer
url_source text
url_title text
url_url text
url_stream bytea
SELECT docass.docass_id AS url_id
, docass.docass_source_id AS url_source_id
, docass.docass_source_type AS url_source
, file.file_title AS url_title
, file.file_descrip AS url_url
, file.file_stream AS url_stream 
FROM (file 
  JOIN docass 
    ON (
           (
                 (docass.docass_target_id = file.file_id)
               AND (docass.docass_target_type = 'FILE'::text)
           )
     )
)
UNION ALLSELECT docass.docass_id AS url_id
, docass.docass_source_id AS url_source_id
, docass.docass_source_type AS url_source
, urlinfo.url_title
, urlinfo.url_url
, NULL::unknown AS url_stream 
FROM (urlinfo 
  JOIN docass 
    ON (
           (
                 (docass.docass_target_id = urlinfo.url_id)
               AND (docass.docass_target_type = 'URL'::text)
           )
     )
);

Index - Schema public


Table: public.urlinfo

public.urlinfo Structure
F-Key Name Type Description
url_id serial PRIMARY KEY
url_title text NOT NULL
url_url text NOT NULL

Index - Schema public


View: public.usr

public.usr Structure
F-Key Name Type Description
usr_id integer
usr_username text
usr_propername text
usr_passwd text
usr_locale_id integer
usr_initials text
usr_agent boolean
usr_active boolean
usr_email text
usr_window text
SELECT (pg_user.usesysid)::integer AS usr_id
, (pg_user.usename)::text AS usr_username
, COALESCE
(
     (
      SELECT usrpref.usrpref_value 
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'propername'::text)
           )
     )
     ,''::text
) AS usr_propername
, NULL::text AS usr_passwd
, COALESCE
(
     (
      SELECT (usrpref.usrpref_value)::integer AS usrpref_value 
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'locale_id'::text)
           )
     )
     , COALESCE
     (
           (
            SELECT locale.locale_id 
              FROM locale 
             WHERE (lower
                       (locale.locale_code) = 'default'::text
                 ) LIMIT 1
           )
           , (
            SELECT locale.locale_id 
              FROM locale 
          ORDER BY locale.locale_id LIMIT 1
           )
     )
) AS usr_locale_id
, COALESCE
(
     (
      SELECT usrpref.usrpref_value 
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'initials'::text)
           )
     )
     ,''::text
) AS usr_initials
, COALESCE
(
     (
      SELECT CASE WHEN 
           (usrpref.usrpref_value = 't'::text) THEN true ELSE false END AS "case"
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'agent'::text)
           )
     )
     , false
) AS usr_agent
, COALESCE
(
     (
      SELECT CASE WHEN 
           (usrpref.usrpref_value = 't'::text) THEN true ELSE false END AS "case"
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'active'::text)
           )
     )
     , usercanlogin
     (
           (pg_user.usename)::text
     )
) AS usr_active
, COALESCE
(
     (
      SELECT usrpref.usrpref_value 
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'email'::text)
           )
     )
     ,''::text
) AS usr_email
, COALESCE
(
     (
      SELECT usrpref.usrpref_value 
        FROM usrpref 
       WHERE (
                 (usrpref.usrpref_username = 
                       (pg_user.usename)::text
                 )
               AND (usrpref.usrpref_name = 'window'::text)
           )
     )
     ,''::text
) AS usr_window 
FROM pg_user;

Index - Schema public


Table: public.usr_bak

User information

public.usr_bak Structure
F-Key Name Type Description
usr_id integer PRIMARY KEY DEFAULT nextval(('usr_usr_id_seq'::text)::regclass)
usr_username text UNIQUE NOT NULL
usr_propername text
usr_passwd text
usr_locale_id integer NOT NULL
usr_initials text
usr_agent boolean NOT NULL
usr_active boolean NOT NULL
usr_email text
usr_window text

Index - Schema public


Table: public.usrgrp

This is which group a user belongs to.

public.usrgrp Structure
F-Key Name Type Description
usrgrp_id serial PRIMARY KEY
public.grp.grp_id usrgrp_grp_id integer NOT NULL
usrgrp_username text NOT NULL

Index - Schema public


Table: public.usrpref

User Preferences information

public.usrpref Structure
F-Key Name Type Description
usrpref_id integer PRIMARY KEY DEFAULT nextval(('usrpref_usrpref_id_seq'::text)::regclass)
usrpref_name text
usrpref_value text
usrpref_username text
usrpref_userpref_name_idx usrpref_name

Index - Schema public


Table: public.usrpriv

User Privileges information

public.usrpriv Structure
F-Key Name Type Description
usrpriv_id integer PRIMARY KEY DEFAULT nextval(('usrpriv_usrpriv_id_seq'::text)::regclass)
usrpriv_priv_id integer
usrpriv_username text

Index - Schema public


Table: public.vendaddrinfo

Vendor Address information

public.vendaddrinfo Structure
F-Key Name Type Description
vendaddr_id integer PRIMARY KEY DEFAULT nextval(('vendaddr_vendaddr_id_seq'::text)::regclass)
vendaddr_vend_id integer
vendaddr_code text
vendaddr_name text
vendaddr_comments text
public.cntct.cntct_id vendaddr_cntct_id integer
public.addr.addr_id vendaddr_addr_id integer
public.taxzone.taxzone_id vendaddr_taxzone_id integer

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.vendinfo

Vendor information

public.vendinfo Structure
F-Key Name Type Description
vend_id integer PRIMARY KEY DEFAULT nextval(('vend_vend_id_seq'::text)::regclass)
vend_name text
vend_lastpurchdate date
vend_active boolean
vend_po boolean
vend_comments text
vend_pocomments text
vend_number text UNIQUE NOT NULL
vend_1099 boolean
vend_exported boolean
vend_fobsource character(1)
vend_fob text
vend_terms_id integer
vend_shipvia text
public.vendtype.vendtype_id vend_vendtype_id integer
vend_qualified boolean
vend_ediemail text
vend_ediemailbody text
vend_edisubject text
vend_edifilename text
vend_accntnum text
vend_emailpodelivery boolean
vend_restrictpurch boolean
vend_edicc text
public.curr_symbol.curr_id vend_curr_id integer DEFAULT basecurrid()
public.cntct.cntct_id vend_cntct1_id integer
public.cntct.cntct_id vend_cntct2_id integer
public.addr.addr_id vend_addr_id integer
vend_match boolean NOT NULL DEFAULT false
vend_ach_enabled boolean NOT NULL DEFAULT false
vend_ach_accnttype text

Type of bank account: K = checKing, C = Cash = savings. These values were chosen to be consistent with bankaccnt_type.
vend_ach_use_vendinfo boolean NOT NULL DEFAULT true
vend_ach_indiv_number text NOT NULL DEFAULT ''::text
vend_ach_indiv_name text NOT NULL DEFAULT ''::text
vend_ediemailhtml boolean NOT NULL DEFAULT false
vend_ach_routingnumber bytea NOT NULL DEFAULT '\\000'::bytea
vend_ach_accntnumber bytea NOT NULL DEFAULT '\\000'::bytea
public.taxzone.taxzone_id vend_taxzone_id integer
vend_accnt_id integer
vend_expcat_id integer DEFAULT (-1)
vend_tax_id integer DEFAULT (-1)

 

public.vendinfo Constraints
Name Constraint
vendinfo_vend_ach_accnttype_check CHECK (((vend_ach_accnttype = 'K'::text) OR (vend_ach_accnttype = 'C'::text)))
vendinfo_vend_number_check CHECK ((vend_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.vendtype

Vendor Type information

public.vendtype Structure
F-Key Name Type Description
vendtype_id serial PRIMARY KEY
vendtype_code text UNIQUE NOT NULL
vendtype_descrip text

 

public.vendtype Constraints
Name Constraint
vendtype_vendtype_code_check CHECK ((vendtype_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.vodist

Voucher distribution information

public.vodist Structure
F-Key Name Type Description
vodist_id integer PRIMARY KEY DEFAULT nextval(('"vodist_vodist_id_seq"'::text)::regclass)
vodist_poitem_id integer
vodist_vohead_id integer
vodist_costelem_id integer
vodist_accnt_id integer
vodist_amount numeric(18,6)
vodist_qty numeric(18,6)
vodist_expcat_id integer DEFAULT (-1)
vodist_tax_id integer DEFAULT (-1)
vodist_discountable boolean NOT NULL DEFAULT true
vodist_notes text

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.vohead

Voucher header information

public.vohead Structure
F-Key Name Type Description
vohead_id integer PRIMARY KEY DEFAULT nextval(('vohead_vohead_id_seq'::text)::regclass)
vohead_number text UNIQUE NOT NULL
vohead_pohead_id integer
vohead_posted boolean
vohead_duedate date
vohead_invcnumber text
vohead_amount numeric(16,4)
vohead_docdate date
vohead_1099 boolean
vohead_distdate date
vohead_reference text
vohead_terms_id integer
public.vendinfo.vend_id vohead_vend_id integer
public.curr_symbol.curr_id vohead_curr_id integer DEFAULT basecurrid()
public.taxtype.taxtype_id vohead_adjtaxtype_id integer
public.taxtype.taxtype_id vohead_freighttaxtype_id integer
vohead_gldistdate date
vohead_misc boolean
public.taxzone.taxzone_id vohead_taxzone_id integer
public.taxtype.taxtype_id vohead_taxtype_id integer
vohead_notes text
vohead_recurring_vohead_id integer

 

public.vohead Constraints
Name Constraint
vohead_vohead_number_check CHECK ((vohead_number <> ''::text))

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.voheadtax

public.voheadtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.vohead.vohead_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.voheadtax Inherits taxhist,

Index - Schema public


Table: public.voitem

Voucher Line Item information

public.voitem Structure
F-Key Name Type Description
voitem_id integer PRIMARY KEY DEFAULT nextval(('"voitem_voitem_id_seq"'::text)::regclass)
voitem_vohead_id integer
voitem_poitem_id integer
voitem_close boolean
voitem_qty numeric(18,6)
voitem_freight numeric(16,4) NOT NULL DEFAULT 0.0
public.taxtype.taxtype_id voitem_taxtype_id integer

Tables referencing this one via Foreign Key Constraints:

Index - Schema public


Table: public.voitemtax

public.voitemtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('taxhist_taxhist_id_seq'::regclass)
public.voitem.voitem_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table public.voitemtax Inherits taxhist,

Index - Schema public


Table: public.whsezone

Warehouse Zone information

public.whsezone Structure
F-Key Name Type Description
whsezone_id serial PRIMARY KEY
whsezone_warehous_id integer NOT NULL
whsezone_name text NOT NULL
whsezone_descrip text

Index - Schema public


Table: public.whsinfo

Warehouse information

public.whsinfo Structure
F-Key Name Type Description
warehous_id integer PRIMARY KEY DEFAULT nextval(('warehous_warehous_id_seq'::text)::regclass)
warehous_code text UNIQUE NOT NULL
warehous_descrip text
warehous_fob text
warehous_active boolean
warehous_counttag_prefix text
warehous_counttag_number integer
warehous_bol_prefix text
warehous_bol_number integer
warehous_shipping boolean
warehous_useslips boolean
warehous_usezones boolean
warehous_aislesize integer
warehous_aislealpha boolean
warehous_racksize integer
warehous_rackalpha boolean
warehous_binsize integer
warehous_binalpha boolean
warehous_locationsize integer
warehous_locationalpha boolean
warehous_enforcearbl boolean
public.accnt.accnt_id warehous_default_accnt_id integer
warehous_shipping_commission numeric(8,4) DEFAULT 0.00
public.cntct.cntct_id warehous_cntct_id integer
public.addr.addr_id warehous_addr_id integer
warehous_transit boolean NOT NULL DEFAULT false
public.shipform.shipform_id warehous_shipform_id integer
public.shipvia.shipvia_id warehous_shipvia_id integer
warehous_shipcomments text
public.costcat.costcat_id warehous_costcat_id integer
public.sitetype.sitetype_id warehous_sitetype_id integer
public.taxzone.taxzone_id warehous_taxzone_id integer
warehous_sequence integer NOT NULL

 

public.whsinfo Constraints
Name Constraint
whsinfo_check CHECK (((warehous_transit AND (warehous_costcat_id IS NOT NULL)) OR (NOT warehous_transit)))
whsinfo_warehous_code_check CHECK ((warehous_code <> ''::text))

Tables referencing this one via Foreign Key Constraints:

warehous_code_key warehous_code bpchar_ops

Index - Schema public


Table: public.wo

Work Order information

public.wo Structure
F-Key Name Type Description
wo_id integer PRIMARY KEY DEFAULT nextval(('wo_wo_id_seq'::text)::regclass)
wo_number integer
wo_subnumber integer
wo_status character(1)
wo_itemsite_id integer
wo_startdate date
wo_duedate date
wo_ordtype character(1)
wo_ordid integer
wo_qtyord numeric(18,6)
wo_qtyrcv numeric(18,6)
wo_adhoc boolean
wo_itemcfg_series integer
wo_imported boolean
wo_wipvalue numeric(16,6)
wo_postedvalue numeric(16,6)
wo_prodnotes text
wo_prj_id integer
wo_priority integer NOT NULL DEFAULT 1
wo_brdvalue numeric(16,6)
wo_bom_rev_id integer DEFAULT (-1)
wo_boo_rev_id integer DEFAULT (-1)
wo_cosmethod character(1)
public.womatl.womatl_id wo_womatl_id integer
wo_username text DEFAULT geteffectivextuser()

 

public.wo Constraints
Name Constraint
chk_wo_cosmethod CHECK ((((wo_cosmethod = NULL::bpchar) OR (wo_cosmethod = 'D'::bpchar)) OR (wo_cosmethod = 'P'::bpchar)))
wo_duedate wo_duedate wo_itemsite_id wo_itemsite_id wo_ordtype wo_ordtype wo_startdate wo_startdate wo_status wo_status

Index - Schema public


Table: public.womatl

Work Order Material Requirements information

public.womatl Structure
F-Key Name Type Description
womatl_id integer PRIMARY KEY DEFAULT nextval(('womatl_womatl_id_seq'::text)::regclass)
womatl_wo_id integer
womatl_itemsite_id integer
womatl_qtyper numeric(20,8) NOT NULL
womatl_scrap numeric(8,4) NOT NULL
womatl_qtyreq numeric(18,6) NOT NULL
womatl_qtyiss numeric(18,6) NOT NULL
womatl_qtywipscrap numeric(18,6) NOT NULL
womatl_lastissue date
womatl_lastreturn date
womatl_cost numeric(16,6)
womatl_picklist boolean
womatl_status character(1)
womatl_imported boolean DEFAULT false
womatl_createwo boolean
womatl_issuemethod character(1)
womatl_wooper_id integer
womatl_bomitem_id integer
womatl_duedate date
womatl_schedatwooper boolean
public.uom.uom_id womatl_uom_id integer NOT NULL
womatl_notes text
womatl_ref text
womatl_scrapvalue numeric(16,6)
womatl_qtyfxd numeric(20,8) NOT NULL

The fixed quantity required
womatl_issuewo boolean NOT NULL DEFAULT false

Tables referencing this one via Foreign Key Constraints:

womatl_itemsite_id_key womatl_itemsite_id womatl_wo_id_key womatl_wo_id

Index - Schema public


Table: public.womatlpost

Table to tie work order to work order material transactions for efficient queries

public.womatlpost Structure
F-Key Name Type Description
womatlpost_id serial PRIMARY KEY
public.womatl.womatl_id womatlpost_womatl_id integer
public.invhist.invhist_id womatlpost_invhist_id integer

Index - Schema public


Table: public.womatlvar

Work Order Material Requirements Variance information

public.womatlvar Structure
F-Key Name Type Description
womatlvar_id integer PRIMARY KEY DEFAULT nextval(('"womatlvar_womatlvar_id_seq"'::text)::regclass)
womatlvar_number integer
womatlvar_subnumber integer
womatlvar_posted date
womatlvar_parent_itemsite_id integer
womatlvar_component_itemsite_id integer
womatlvar_qtyord numeric(18,6)
womatlvar_qtyrcv numeric(18,6)
womatlvar_qtyiss numeric(18,6)
womatlvar_qtyper numeric(18,6)
womatlvar_scrap numeric(18,6)
womatlvar_wipscrap numeric(18,6)
womatlvar_bomitem_id integer
womatlvar_ref text
womatlvar_notes text
womatlvar_qtyfxd numeric(20,8) NOT NULL

The fixed quantity required

Index - Schema public


Table: public.xsltmap

Mapping of XML System identifiers to XSLT transformation files

public.xsltmap Structure
F-Key Name Type Description
xsltmap_id serial PRIMARY KEY
xsltmap_name text UNIQUE NOT NULL
xsltmap_doctype text NOT NULL
xsltmap_system text NOT NULL
xsltmap_import text NOT NULL
xsltmap_export text NOT NULL DEFAULT ''::text

 

public.xsltmap Constraints
Name Constraint
xsltmap_check CHECK (((xsltmap_doctype <> ''::text) OR (xsltmap_system <> ''::text)))
xsltmap_xsltmap_importexport_check CHECK (((xsltmap_import <> ''::text) OR (xsltmap_export <> ''::text)))
xsltmap_xsltmap_name_check CHECK ((xsltmap_name <> ''::text))

Index - Schema public


Table: public.yearperiod

Accounting Year Periods information

public.yearperiod Structure
F-Key Name Type Description
yearperiod_id serial PRIMARY KEY
yearperiod_start date NOT NULL
yearperiod_end date NOT NULL
yearperiod_closed boolean NOT NULL DEFAULT false

Index - Schema public


Function: public._accntdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _accntnum     TEXT := formatGLAccount(OLD.accnt_id);
  _check INTEGER;
BEGIN
-- This trigger is to protect against accounts that are in use

--  Check to see if the passed accnt is used in a Cost Category
  SELECT costcat_id INTO _check
  FROM costcat
  WHERE ( (costcat_asset_accnt_id=OLD.accnt_id)
     OR   (costcat_liability_accnt_id=OLD.accnt_id)
     OR   (costcat_adjustment_accnt_id=OLD.accnt_id)
     OR   (costcat_purchprice_accnt_id=OLD.accnt_id)
     OR   (costcat_laboroverhead_accnt_id=OLD.accnt_id)
     OR   (costcat_scrap_accnt_id=OLD.accnt_id)
     OR   (costcat_invcost_accnt_id=OLD.accnt_id)
     OR   (costcat_wip_accnt_id=OLD.accnt_id)
     OR   (costcat_shipasset_accnt_id=OLD.accnt_id)
     OR   (costcat_mfgscrap_accnt_id=OLD.accnt_id)
     OR   (costcat_transform_accnt_id=OLD.accnt_id)
     OR   (costcat_freight_accnt_id=OLD.accnt_id) )
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Cost Category';
  END IF;

--  Check to see if the passed accnt is used in a Sales Account Assignment
  SELECT salesaccnt_id INTO _check
  FROM salesaccnt
  WHERE ( (salesaccnt_sales_accnt_id=OLD.accnt_id)
     OR   (salesaccnt_credit_accnt_id=OLD.accnt_id)
     OR   (salesaccnt_cos_accnt_id=OLD.accnt_id) )
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Sales Account Assignment';
  END IF;

--  Check to see if the passed accnt is used in a A/R Account Assignment
  SELECT araccnt_id INTO _check
  FROM araccnt
  WHERE ( (araccnt_freight_accnt_id=OLD.accnt_id)
     OR   (araccnt_ar_accnt_id=OLD.accnt_id)
     OR   (araccnt_prepaid_accnt_id=OLD.accnt_id) )
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in A/R Account Assignment';
  END IF;

--  Check to see if the passed accnt is used in a Warehouse
  SELECT warehous_id INTO _check
  FROM whsinfo
  WHERE (warehous_default_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Site';
  END IF;

--  Check to see if the passed accnt is used in a Bank Account
  SELECT bankaccnt_id INTO _check
  FROM bankaccnt
  WHERE (bankaccnt_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Bank Account';
  END IF;

--  Check to see if the passed accnt is used in an Expense Category
  SELECT expcat_id INTO _check
  FROM expcat
  WHERE ( (expcat_exp_accnt_id=OLD.accnt_id)
     OR   (expcat_liability_accnt_id=OLD.accnt_id)
     OR   (expcat_purchprice_accnt_id=OLD.accnt_id)
     OR   (expcat_freight_accnt_id=OLD.accnt_id) )
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Expense Category';
  END IF;

--  Check to see if the passed accnt is used in a Tax Code
  SELECT tax_id INTO _check
  FROM tax
  WHERE (tax_sales_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Tax Code';
  END IF;

--  Check to see if the passed accnt is used in a Standard Journal Item
  SELECT stdjrnlitem_id INTO _check
  FROM stdjrnlitem
  WHERE (stdjrnlitem_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Standard Journal Item';
  END IF;

--  Check to see if the passed accnt is used in a A/P Account Assignment
  SELECT apaccnt_ap_accnt_id INTO _check
  FROM apaccnt
  WHERE ( (apaccnt_ap_accnt_id=OLD.accnt_id)
     OR   (apaccnt_prepaid_accnt_id=OLD.accnt_id)
     OR   (apaccnt_discount_accnt_id=OLD.accnt_id) )
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in A/P Account Assignment';
  END IF;

--  Check to see if the passed accnt is used in an A/R Open Item record
  SELECT aropen_accnt_id INTO _check
    FROM aropen
   WHERE (aropen_accnt_id=OLD.accnt_id)
   LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in A/R Open Item';
  END IF;

--  Check to see if the passed accnt has been used in the G/L
  SELECT gltrans_accnt_id INTO _check
  FROM gltrans
  WHERE (gltrans_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in G/L Transaction';
  END IF;

  SELECT sltrans_accnt_id INTO _check
  FROM sltrans
  WHERE (sltrans_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in G/L Journal Transaction';
  END IF;

  SELECT glseries_accnt_id INTO _check
  FROM glseries
  WHERE (glseries_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in G/L Series';
  END IF;

  SELECT trialbal_accnt_id INTO _check
  FROM trialbal
  WHERE (trialbal_accnt_id=OLD.accnt_id)
    AND (trialbal_beginning != 0 OR trialbal_ending != 0)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Trial Balance';
  END IF;

  SELECT cashrcptmisc_accnt_id INTO _check
  FROM cashrcptmisc
  WHERE (cashrcptmisc_accnt_id=OLD.accnt_id)
  LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Can not delete, used in Cash Receipt Misc. Application';
  END IF;

  -- TODO: everything above here should be replaced by fkeys
  IF (OLD.accnt_id = fetchMetricValue('DefaultAPAccount')) THEN
    RAISE EXCEPTION 'Cannot delete the default A/P Account [xtuple: accnt, -1, %]',
                    _accntnum;
  ELSIF (OLD.accnt_id = fetchMetricValue('DefaultARAccount')) THEN
    RAISE EXCEPTION 'Cannot delete the default A/R Account [xtuple: accnt, -2, %]',
                    _accntnum;
  END IF;

  RETURN OLD;
END;

Function: public._accnttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ffSub BOOLEAN;
  ffProfit BOOLEAN;
  result INTEGER;
BEGIN
  SELECT (metric_value='t')
    INTO ffSub
    FROM metric
   WHERE(metric_name='GLFFSubaccounts')
   LIMIT 1;
  ffSub := COALESCE(ffSub, false);

  SELECT (metric_value='t')
    INTO ffProfit
    FROM metric
   WHERE(metric_name='GLFFProfitCenters')
   LIMIT 1;
  ffProfit := COALESCE(ffSub, false);

  IF (NEW.accnt_sub IS NOT NULL AND ffSub = false) THEN
    SELECT subaccnt_id
      INTO result
      FROM subaccnt
     WHERE(subaccnt_number=NEW.accnt_sub)
     LIMIT 1;
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'You must supply a valid Sub Account Number.';
    END IF;
  END IF;

  IF (NEW.accnt_profit IS NOT NULL AND ffProfit = false) THEN
    SELECT prftcntr_id
      INTO result
      FROM prftcntr
     WHERE(prftcntr_number=NEW.accnt_profit)
     LIMIT 1;
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'You must supply a valid Profit Center Number.';
    END IF;
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    IF ((NEW.accnt_type != OLD.accnt_type) AND
        (SELECT (count(*) > 0) FROM gltrans WHERE (gltrans_accnt_id=NEW.accnt_id))) THEN
      RAISE EXCEPTION 'You may not change the account type of an account that has transaction history';
    END IF;
  END IF;

  NEW.accnt_name := formatGlAccount(NEW.accnt_company, NEW.accnt_profit, NEW.accnt_number, NEW.accnt_sub);

  RETURN NEW;
END;

Function: public._accntuniquetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
BEGIN
  -- This trigger is to protect against id collision on inherited tables since there is no way 
  -- to enforce that with regular constraints.  It should be applied to accnt and any table that 
  -- inherits accnt.
  IF (SELECT (count(accnt_id) > 0) FROM accnt WHERE (accnt_id = NEW.accnt_id)) THEN
    RAISE EXCEPTION 'Can not create record on account with duplicate key %.', NEW.accnt_id;
  END IF;
  
  RETURN NEW;
END;

Function: public._addrtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  DECLARE
    _uses	INTEGER	:= 0;

  BEGIN

    IF (TG_OP = 'INSERT') THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('AddressNumber', NEW.addr_number);
    ELSE
      SELECT count(*) INTO _uses
      FROM cntct
      WHERE ((cntct_addr_id=OLD.addr_id)
        AND   cntct_active);
    END IF;

    IF (TG_OP = 'UPDATE') THEN
      IF (OLD.addr_active AND NOT NEW.addr_active AND _uses > 0) THEN
	RAISE EXCEPTION 'Cannot inactivate Address with Active Contacts (%)',
			_uses;
      END IF;
    ELSIF (TG_OP = 'DELETE') THEN
      IF (_uses > 0) THEN
	RAISE EXCEPTION 'Cannot Delete Address with Active Contacts (%)',
			_uses;
      END IF;

      UPDATE cntct SET cntct_addr_id = NULL
      WHERE ((cntct_addr_id=OLD.addr_id)
	AND  (NOT cntct_active));

      RETURN OLD;
    END IF;

    RETURN NEW;
  END;

Function: public._alarmbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  BEGIN
    PERFORM clearNumberIssue('AlarmNumber', NEW.alarm_number);

    RETURN NEW;
  END;

Function: public._apapplytrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _tpaid NUMERIC;

BEGIN

-- get the exchange rate for the doc date
  IF (TG_OP = 'INSERT') THEN
    SELECT currtocurr(NEW.apapply_curr_id,apopen_curr_id,NEW.apapply_amount,NEW.apapply_postdate) 
      INTO _tpaid
    FROM apopen
    WHERE ( apopen_id=NEW.apapply_target_apopen_id );
    IF (FOUND) THEN
      NEW.apapply_target_paid := _tpaid;
    ELSE
      RAISE EXCEPTION 'Error calculating paid amount on application';
    END IF;
  END IF;

  RETURN NEW;

END;


Function: public._apopentrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _currrate NUMERIC;

BEGIN

-- get the base exchange rate for the doc date
  IF (TG_OP = 'INSERT' AND NEW.apopen_curr_rate IS NULL) THEN
    SELECT curr_rate INTO _currrate
    FROM curr_rate
    WHERE ( (NEW.apopen_curr_id=curr_id)
    AND ( NEW.apopen_docdate BETWEEN curr_effective 
                                 AND curr_expires) );
    IF (FOUND) THEN
      NEW.apopen_curr_rate := _currrate;
    ELSE
      RAISE EXCEPTION 'Currency exchange rate not found';
    END IF;
  END IF;

  NEW.apopen_open := NEW.apopen_amount > NEW.apopen_paid;

  IF (TG_OP = 'INSERT') THEN
    IF (NEW.apopen_open=FALSE) THEN
      NEW.apopen_status='C';
    ELSE
      NEW.apopen_status='O';
    END IF;

     --- clear the number from the issue cache
    PERFORM clearNumberIssue('APMemoNumber', NEW.apopen_docnumber);
  END IF;
  
  IF (TG_OP = 'UPDATE') THEN
    IF ((OLD.apopen_open=TRUE) AND (NEW.apopen_open=FALSE)) THEN
      NEW.apopen_status='C';
      IF (NEW.apopen_closedate IS NULL) THEN
        NEW.apopen_closedate=CURRENT_DATE;
      END IF;
    END IF;
    
    IF ((OLD.apopen_open=FALSE) AND (NEW.apopen_open=TRUE)) THEN
      NEW.apopen_status='O';
      NEW.apopen_closedate=NULL;
    END IF;
  END IF;

  RETURN NEW;

END;


Function: public._arapplytrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _tpaid NUMERIC;

BEGIN

-- get the exchange rate for the doc date
  IF (TG_OP = 'INSERT') THEN
    IF (NEW.arapply_target_doctype != 'K') THEN 
      SELECT round(currtocurr(NEW.arapply_curr_id,aropen_curr_id,NEW.arapply_applied,NEW.arapply_postdate),2) 
        INTO NEW.arapply_target_paid
      FROM aropen
      WHERE ( aropen_id=NEW.arapply_target_aropen_id );
    ELSE
      SELECT round(currtocurr(NEW.arapply_curr_id,aropen_curr_id,NEW.arapply_applied,NEW.arapply_postdate),2) 
        INTO NEW.arapply_target_paid
      FROM aropen
      WHERE ( aropen_id=NEW.arapply_source_aropen_id );
    END IF;
    IF NOT FOUND THEN
      NEW.arapply_target_paid := NEW.arapply_applied;
    END IF;
  END IF;

  RETURN NEW;

END;


Function: public._aropenaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _openAmount NUMERIC;
  _lateCount INTEGER := 0;
  _graceDays INTEGER;
  _checkLate BOOLEAN := false;
  _checkLimit BOOLEAN := false;
  _id INTEGER;
BEGIN

  IF (TG_OP = 'INSERT') THEN
    _id := NEW.aropen_id;
  ELSE
    _id := OLD.aropen_id;
  END IF;
-- If metric is set then auto close any associated incidents when AR is closed
  IF (fetchMetricBool('AutoCloseARIncident')) THEN
    IF (NEW.aropen_open = FALSE) THEN
      UPDATE incdt SET incdt_status='L' WHERE (incdt_aropen_id=_id);
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._aropentrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _openAmount NUMERIC;
  _p RECORD;
  _lateCount INTEGER := 0;
  _graceDays INTEGER;
  _checkLate BOOLEAN := false;
  _checkLimit BOOLEAN := false;
  _id INTEGER;
  _currRate NUMERIC;
BEGIN
  -- Checks
  -- Start with privileges
  IF ( (NOT checkPrivilege('MaintainARMemos')) AND
       (NOT checkPrivilege('PostMiscInvoices')) AND
       (NOT checkPrivilege('PostARDocuments')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain A/R Memos.';
  END IF;

  IF ( (NEW.aropen_docnumber IS NULL) OR (LENGTH(NEW.aropen_docnumber) = 0) ) THEN
    RAISE EXCEPTION 'You must enter a valid Document # for this A/R Memo.';
  END IF;

  IF ( (NEW.aropen_amount IS NOT NULL) AND (NEW.aropen_amount < 0) ) THEN
    RAISE EXCEPTION 'You must enter a positive Amount for this A/R Memo.';
  END IF;

  IF (TG_OP IN ('INSERT', 'UPDATE') AND NEW.aropen_cust_id < 0) THEN
    RAISE NOTICE 'Fixing deprecated use of negative aropen_cust_id';
    NEW.aropen_cust_id := NULL;
  END IF;

  IF (TG_OP IN ('INSERT', 'UPDATE') AND NEW.aropen_salesrep_id < 0) THEN
    RAISE NOTICE 'Fixing deprecated use of negative aropen_salesrep_id';
    NEW.aropen_salesrep_id := NULL;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    SELECT aropen_id INTO _id
    FROM aropen
    WHERE ( (aropen_doctype=NEW.aropen_doctype)
      AND   (aropen_docnumber=NEW.aropen_docnumber) )
    LIMIT 1;
    IF (FOUND) THEN
      RAISE EXCEPTION 'This Document Type/Number already exists. You may not enter a duplicate A/R Memo.';
    END IF;

    --- clear the number from the issue cache if applicable
    PERFORM clearNumberIssue('ARMemoNumber', NEW.aropen_docnumber);
  END IF;

-- Determine the number of late invoices
  IF ( SELECT (metric_value='t')
         FROM metric
        WHERE(metric_name='AutoCreditWarnLateCustomers')) THEN
    _checkLate := true;

    SELECT COALESCE(metric_value::integer, _graceDays)
      INTO _graceDays
      FROM metric
     WHERE(metric_name='DefaultAutoCreditWarnGraceDays');
    IF (NOT FOUND) THEN
      _graceDays := 30;
    END IF;
    SELECT COALESCE(cust_gracedays, _graceDays)
      INTO _graceDays
      FROM custinfo
     WHERE(cust_id=NEW.aropen_cust_id);
    IF (NOT FOUND) THEN
      _graceDays := 30;
    END IF;

    SELECT count(aropen_id)
      INTO _lateCount
      FROM aropen
     WHERE((NEW.aropen_cust_id = aropen_cust_id)
       AND (aropen_open)
       AND (aropen_amount > aropen_paid)
       AND (aropen_doctype IN ('I', 'D'))
       AND (aropen_duedate < (CURRENT_DATE - _graceDays)));

  --  Adjust _lateCount if late invoice being paid
    IF ( (NEW.aropen_paid = NEW.aropen_amount)
     AND (NEW.aropen_doctype IN ('I', 'D'))
     AND (NEW.aropen_duedate < (CURRENT_DATE - _graceDays))) THEN
      _lateCount := _lateCount - 1;
    END IF;
  END IF;

-- get the base exchange rate for the doc date
  IF (TG_OP = 'INSERT' AND NEW.aropen_curr_rate IS NULL) THEN
    SELECT curr_rate INTO _currrate
      FROM curr_rate
    WHERE ( (NEW.aropen_curr_id=curr_id)
      AND ( NEW.aropen_docdate BETWEEN curr_effective 
                                   AND curr_expires) );
    IF (FOUND) THEN
      NEW.aropen_curr_rate := _currrate;
    ELSE
      RAISE EXCEPTION 'Currency exchange rate not found';
    END IF;
  END IF;

--  Close this aropen if it is paid
  IF (NEW.aropen_paid = NEW.aropen_amount) THEN
    NEW.aropen_open=FALSE;

--  Remove any aropenalloc regards that reference this aropen item
    DELETE FROM aropenalloc WHERE (aropenalloc_aropen_id=NEW.aropen_id);
  END IF;

  IF (TG_OP = 'INSERT') THEN
    IF (NEW.aropen_open=FALSE) 
    AND (NEW.aropen_closedate IS NULL) THEN
      NEW.aropen_closedate=current_date;
    END IF;
  END IF;
  
  IF (TG_OP = 'UPDATE') THEN
    IF ((OLD.aropen_open=TRUE) 
    AND (NEW.aropen_open=FALSE) 
    AND (NEW.aropen_closedate IS NULL)) THEN
      NEW.aropen_closedate=current_date;
    END IF;
  END IF;

--  Only check if the customer in question has a non-zero Credit Limit
  SELECT cust_id, cust_creditlmt, cust_creditstatus,
         cust_autoupdatestatus, cust_autoholdorders INTO _p
  FROM custinfo
  WHERE (cust_id=NEW.aropen_cust_id);
  IF (_p.cust_creditlmt > 0) THEN
    _checkLimit := true;

    SELECT COALESCE(SUM( CASE WHEN (aropen_doctype IN ('I', 'D')) THEN (aropen_amount - aropen_paid)
                     ELSE ((aropen_amount - aropen_paid) * -1)
                END ), 0.0) INTO _openAmount
    FROM aropen AS current
    WHERE ( (current.aropen_cust_id=NEW.aropen_cust_id)
     AND (current.aropen_open)
     AND (current.aropen_id <> NEW.aropen_id) );

--  Add in the value of the current aropen item
    IF (NEW.aropen_doctype IN ('I', 'D')) THEN
      _openAmount := (_openAmount + (NEW.aropen_amount - NEW.aropen_paid));
    ELSE
      _openAmount := (_openAmount - (NEW.aropen_amount - NEW.aropen_paid));
    END IF;
  ELSE
    _openAmount := 0;
  END IF;

  IF (_checkLimit OR _checkLate) THEN
--  Handle a Customer that is going under its credit limit
    IF ((_p.cust_creditlmt >= _openAmount) AND (_lateCount <= 0)) THEN

--  Handle the Customer Status
      IF ( (_p.cust_autoupdatestatus) AND (_p.cust_creditstatus='W') ) THEN
        UPDATE custinfo
        SET cust_creditstatus='G'
        WHERE (cust_id=NEW.aropen_cust_id);
      END IF;

--  Handle the open Sales Orders
      IF (_p.cust_autoholdorders) THEN
        UPDATE cohead
        SET cohead_holdtype='N'
        FROM coitem
        WHERE ( (coitem_cohead_id=cohead_id)
         AND (cohead_holdtype='C')
         AND (coitem_status='O')
         AND (cohead_cust_id=_p.cust_id) );
      END IF;

--  Handle a Customer that is going over its credit limit
    ELSIF ((_p.cust_creditlmt < _openAmount) OR (_lateCount > 0)) THEN

--  Handle the Customer Status
      IF ( (_p.cust_autoupdatestatus) AND (_p.cust_creditstatus = 'G') ) THEN
        UPDATE custinfo
        SET cust_creditstatus='W'
        WHERE (cust_id=NEW.aropen_cust_id);
      END IF;

--  Handle the open Sales Orders
      IF (_p.cust_autoholdorders) THEN
        UPDATE cohead
        SET cohead_holdtype='C'
        FROM coitem
        WHERE ( (coitem_cohead_id=cohead_id)
         AND (cohead_holdtype='N')
         AND (coitem_status='O')
         AND (cohead_cust_id=_p.cust_id) );
      END IF;

    END IF;

  END IF;

  RETURN NEW;

END;

Function: public._bomheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _revid INTEGER;
  _check TEXT;
BEGIN
-- Privilege Checks
  IF (NOT checkPrivilege('MaintainBOMs')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Bills of Material.';
  END IF;
  
  RETURN NEW;
END;

Function: public._bomitemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  IF ( SELECT fetchMetricBool('ItemChangeLog') ) THEN
    IF (TG_OP = 'INSERT') THEN
      PERFORM postComment('ChangeLog', 'BMI', NEW.bomitem_id, ('Created BOM Item Sequence ' || NEW.bomitem_seqnumber::TEXT));

    ELSIF (TG_OP = 'UPDATE') THEN
      IF (NEW.bomitem_effective <> OLD.bomitem_effective) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Effective Date Changed from ' || formatDate(OLD.bomitem_effective, 'Always') ||
                               ' to ' || formatDate(NEW.bomitem_effective, 'Always' ) ) );
      END IF;

      IF (NEW.bomitem_expires <> OLD.bomitem_expires) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Expiration Date Changed from ' || formatDate(OLD.bomitem_expires, 'Never') ||
                               ' to ' || formatDate(NEW.bomitem_expires, 'Never' ) ) );
      END IF;

      IF (NEW.bomitem_qtyfxd <> OLD.bomitem_qtyfxd) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Fixed Qty. Changed from ' || formatQtyPer(OLD.bomitem_qtyfxd) ||
                               ' to ' || formatQtyPer(NEW.bomitem_qtyfxd ) ) );
      END IF;

      IF (NEW.bomitem_qtyper <> OLD.bomitem_qtyper) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Qty. Per Changed from ' || formatQtyPer(OLD.bomitem_qtyper) ||
                               ' to ' || formatQtyPer(NEW.bomitem_qtyper ) ) );
      END IF;

      IF (NEW.bomitem_scrap <> OLD.bomitem_scrap) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Scrap % Changed from ' || formatPrcnt(OLD.bomitem_scrap) ||
                               ' to ' || formatPrcnt(NEW.bomitem_scrap ) ) );
      END IF;

      IF (NEW.bomitem_issuemethod <> OLD.bomitem_issuemethod) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'Issue Method Changed from ' || (CASE WHEN(OLD.bomitem_issuemethod='S') THEN 'Push'
                                                                     WHEN(OLD.bomitem_issuemethod='L') THEN 'Pull'
                                                                     WHEN(OLD.bomitem_issuemethod='M') THEN 'Mixed'
                                                                     ELSE OLD.bomitem_issuemethod END) ||
                               ' to ' || (CASE WHEN(NEW.bomitem_issuemethod='S') THEN 'Push'
                                               WHEN(NEW.bomitem_issuemethod='L') THEN 'Pull'
                                               WHEN(NEW.bomitem_issuemethod='M') THEN 'Mixed'
                                               ELSE NEW.bomitem_issuemethod END) ) );
      END IF;

      IF (NEW.bomitem_ecn <> OLD.bomitem_ecn) THEN
        PERFORM postComment( 'ChangeLog', 'BMI', NEW.bomitem_id,
                             ( 'ECN Changed from ' || OLD.bomitem_ecn ||
                               ' to ' || NEW.bomitem_ecn ) );
      END IF;

      IF (OLD.bomitem_createwo <> NEW.bomitem_createwo) THEN
        IF (NEW.bomitem_createwo) THEN
          PERFORM postComment('ChangeLog', 'BMI', NEW.bomitem_id, 'Create Child W/O activated');
        ELSE
          PERFORM postComment('ChangeLog', 'BMI', NEW.bomitem_id, 'Create Child W/O deactivated');
        END IF;
      END IF;

      IF (OLD.bomitem_issuewo <> NEW.bomitem_issuewo) THEN
        IF (NEW.bomitem_issuewo) THEN
          PERFORM postComment('ChangeLog', 'BMI', NEW.bomitem_id, 'Issue Child W/O activated');
        ELSE
          PERFORM postComment('ChangeLog', 'BMI', NEW.bomitem_id, 'Issue Child W/O deactivated');
        END IF;
      END IF;

    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    DELETE FROM comment
     WHERE ( (comment_source='BMI')
       AND   (comment_source_id=OLD.bomitem_id) );

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._bomitembeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
BEGIN

  DELETE FROM comment
   WHERE ( (comment_source='BMI')
     AND   (comment_source_id=OLD.bomitem_id) );

  RETURN OLD;
END;

Function: public._bomitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _bomworksetid INTEGER;
  _bomworkid INTEGER;
  _seqNumber INTEGER;
  _parentItem RECORD;
BEGIN

  -- Privilege Checks
  IF (NOT checkPrivilege('MaintainBOMs')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Bills of Material.';
  END IF;

  -- Cache Parent Item
   SELECT * INTO _parentItem
   FROM item
   WHERE (item_id=NEW.bomitem_parent_item_id);

  IF (TG_OP = 'INSERT') THEN
    --  Make sure that the parent and component are not the same
    IF (NEW.bomitem_parent_item_id = NEW.bomitem_item_id) THEN
      RAISE EXCEPTION 'BOM Item Parent and Component Item cannot be the same. [xtuple: createBOMItem, -1]';
    END IF;

    --  Make sure that the parent is not used in the component at some level
    IF ( SELECT (item_type IN ('M', 'F'))
         FROM item
         WHERE (item_id=NEW.bomitem_item_id) ) THEN
      SELECT indentedWhereUsed(NEW.bomitem_parent_item_id) INTO _bomworksetid;
      SELECT bomwork_id INTO _bomworkid
      FROM bomwork
      WHERE ((bomwork_set_id=_bomworksetid)
        AND  (bomwork_item_id=NEW.bomitem_item_id))
      LIMIT 1;
      IF (FOUND) THEN
        PERFORM deleteBOMWorkset(_bomworksetid);
        RAISE EXCEPTION 'BOM Item Parent is used by Component, BOM is recursive. [xtuple: createBOMItem, -2]';
      END IF;
    END IF;

    PERFORM deleteBOMWorkset(_bomworksetid);

    -- Set defaults
    NEW.bomitem_rev_id := COALESCE(NEW.bomitem_rev_id, -1);
    NEW.bomitem_booitem_seq_id := COALESCE(NEW.bomitem_booitem_seq_id, -1);
    NEW.bomitem_schedatwooper := COALESCE(NEW.bomitem_schedatwooper, FALSE);
    IF (NEW.bomitem_seqnumber IS NULL) THEN
      --  Grab the next Sequence Number, if any
      SELECT MAX(bomitem_seqnumber) INTO _seqNumber
      FROM bomitem(NEW.bomitem_parent_item_id,NEW.bomitem_rev_id);
      IF (_seqNumber IS NOT NULL) THEN
        NEW.bomitem_seqnumber := (_seqNumber + 10);
      ELSE
        NEW.bomitem_seqnumber := 10;
      END IF;
    END IF;
  END IF; -- end Insert specific

  IF (TG_OP = 'UPDATE') THEN
    -- Disallow changes that would compromise revision control integrity
    IF (NEW.bomitem_parent_item_id != OLD.bomitem_parent_item_id) THEN
      RAISE EXCEPTION 'Parent Item ID may not be changed.';
    END IF;

    IF (NEW.bomitem_item_id != OLD.bomitem_item_id) THEN
      RAISE EXCEPTION 'Item ID may not be changed.';
    END IF;

    IF ((fetchMetricBool('RevControl')) AND (OLD.bomitem_rev_id > -1)) THEN
      IF (SELECT (rev_status = 'I') FROM rev WHERE (rev_id=OLD.bomitem_rev_id)) THEN
        RAISE EXCEPTION 'Bill of material is Inactive and may not be modified';
      END IF;
    END IF;
  END IF; -- end Update specific

  -- Check for valid UOM
  IF (SELECT (count(*) != 1)
      FROM
             (SELECT uom_id
                FROM item JOIN uom ON (item_inv_uom_id=uom_id)
                WHERE(item_id=NEW.bomitem_item_id)
              UNION 
              SELECT uom_id
                FROM item JOIN itemuomconv ON (itemuomconv_item_id=item_id)
                          JOIN uom ON (itemuomconv_to_uom_id=uom_id),
                     itemuom, uomtype 
               WHERE((itemuomconv_from_uom_id=item_inv_uom_id)
                 AND (item_id=NEW.bomitem_item_id) 
                 AND (itemuom_itemuomconv_id=itemuomconv_id) 
                 AND (uomtype_id=itemuom_uomtype_id) 
                 AND (uomtype_name='MaterialIssue'))
              UNION 
              SELECT uom_id
                FROM item JOIN itemuomconv ON (itemuomconv_item_id=item_id)
                          JOIN uom ON (itemuomconv_from_uom_id=uom_id),
                     itemuom, uomtype 
               WHERE((itemuomconv_to_uom_id=item_inv_uom_id)
                 AND (item_id=NEW.bomitem_item_id) 
                 AND (itemuom_itemuomconv_id=itemuomconv_id) 
                 AND (uomtype_id=itemuom_uomtype_id) 
                 AND (uomtype_name='MaterialIssue'))) AS data
        WHERE (uom_id=NEW.bomitem_uom_id)) THEN
    RAISE EXCEPTION 'Unit of Measure Invalid for Material Issue.';
  END IF;

-- Disallow configuration parameters if parent is not a job item
   IF (NEW.bomitem_char_id IS NOT NULL) THEN
     IF (NOT _parentItem.item_config) THEN
       RAISE EXCEPTION 'Configuration characteristics may only be defined for Configured Items';
     END IF;
   END IF;

  -- Kit items must be sold and not kits themselves
  IF (_parentItem.item_type = 'K') THEN
    IF (SELECT (COUNT(item_id) = 0)
          FROM item
         WHERE ((item_id=NEW.bomitem_item_id)
           AND (item_sold)
           AND (item_type != 'K'))) THEN
       RAISE EXCEPTION 'Bill of Material Items for kits must be sold and not kits themselves';
     END IF;
   END IF;

  -- Over ride logic to disallow invalid data
  IF (NEW.bomitem_createwo) THEN
    IF (SELECT (item_type != 'M') 
          FROM item 
         WHERE (item_id=NEW.bomitem_item_id)) THEN
      NEW.bomitem_createwo := FALSE;
    END IF;
    IF (NEW.bomitem_booitem_seq_id = -1) THEN
      NEW.bomitem_schedatwooper := FALSE;
    END IF;
  END IF;

  NEW.bomitem_moddate := COALESCE(NEW.bomitem_moddate, CURRENT_DATE);

  RETURN NEW;
END;

Function: public._bomitemsubtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
  IF (NOT checkPrivilege('MaintainBOMs')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Bills of Material.';
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;

END;

Function: public._cashrcptitemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _total      NUMERIC;

BEGIN

  -- Checks
  -- Total Over Application Warning
  SELECT (cashrcpt_amount - SUM(COALESCE(cashrcptitem_amount, 0))) INTO _total
  FROM cashrcptitem JOIN cashrcpt ON (cashrcpt_id=cashrcptitem_cashrcpt_id)
  WHERE (cashrcptitem_cashrcpt_id=NEW.cashrcptitem_cashrcpt_id)
  GROUP BY cashrcpt_amount;
  IF (_total < 0.0) THEN
    RAISE WARNING 'Warning -- the Cash Receipt has been over applied.';
  END IF;
  
  RETURN NEW;

END;

Function: public._cashrcptitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _openAmount NUMERIC;

BEGIN

  -- Checks
  -- Start with Privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add a new Cash Receipt Application.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Cash Receipt Application.';
    END IF;
  END IF;

  -- Over Application
  SELECT round(currToCurr(aropen_curr_id, cashrcpt_curr_id,
               aropen_amount - aropen_paid, cashrcpt_distdate) -
               COALESCE((SELECT SUM(cashrcptitem_amount)
                           FROM cashrcptitem, cashrcpt
                           WHERE ((cashrcpt_id=cashrcptitem_cashrcpt_id)
                             AND  (NOT cashrcpt_void)
                             AND  (NOT cashrcpt_posted)
                             AND  (cashrcpt_id != NEW.cashrcptitem_cashrcpt_id)
                             AND  (cashrcptitem_aropen_id=NEW.cashrcptitem_aropen_id))), 0),2) INTO _openAmount
  FROM aropen, cashrcpt
  WHERE ( (aropen_id=NEW.cashrcptitem_aropen_id)
    AND   (cashrcpt_id=NEW.cashrcptitem_cashrcpt_id) );
  IF (NEW.cashrcptitem_amount > _openAmount) THEN
    RAISE EXCEPTION 'You may not apply more than the balance of this item.';
  END IF;


  RETURN NEW;

END;

Function: public._cashrcptmisctrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;

BEGIN

  -- Checks
  -- Start with Privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add a new Cash Receipt Misc. Application.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Cash Receipt Misc. Application.';
    END IF;
  END IF;

  -- Account is required
  IF (NEW.cashrcptmisc_accnt_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid GL Account.';
  END IF;

  -- Amount is required
  IF (COALESCE(NEW.cashrcptmisc_amount, 0) = 0) THEN
    RAISE EXCEPTION 'You must supply a valid Amount.';
  END IF;

  RETURN NEW;

END;

Function: public._cashrcpttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _checkId    INTEGER;
  _currId     INTEGER;
  _bankCurrId INTEGER;
  _evntType   TEXT;
  _whsId      INTEGER;
  _custNumber TEXT;
  _currrate   NUMERIC;

BEGIN

  -- Checks
  -- Start with privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add new Cash Receipts.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainCashReceipts') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Cash Receipt.';
    END IF;
  END IF;

  -- Currency must be same as Bank Currency
  IF (TG_OP = 'INSERT') THEN
    _currId = COALESCE(NEW.cashrcpt_curr_id, basecurrid());

     --- clear the number from the issue cache
    PERFORM clearNumberIssue('CashRcptNumber', NEW.cashrcpt_number);
  ELSE
    _currId = NEW.cashrcpt_curr_id;
  END IF;

-- get the base exchange rate for the dist date
  IF (NEW.cashrcpt_curr_rate IS NULL) THEN
    SELECT curr_rate INTO _currrate
    FROM curr_rate
    WHERE ( (NEW.cashrcpt_curr_id=curr_id)
      AND ( NEW.cashrcpt_distdate BETWEEN curr_effective 
                                 AND curr_expires) );
    IF (FOUND) THEN
      NEW.cashrcpt_curr_rate := _currrate;
    ELSE
      RAISE EXCEPTION 'Currency exchange rate not found';
    END IF;
  END IF;

  -- Create CashReceiptPosted Event
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.cashrcpt_posted=FALSE AND NEW.cashrcpt_posted=TRUE) THEN
      _evntType = 'CashReceiptPosted';
      -- Find the warehouse for which to create evntlog entries
      SELECT usrpref_value  INTO _whsId
      FROM usrpref
      WHERE usrpref_username = getEffectiveXtUser()
        AND usrpref_name = 'PreferredWarehouse';
      -- Find the Customer Number
      SELECT cust_number INTO _custNumber
      FROM custinfo
      WHERE (cust_id=NEW.cashrcpt_cust_id);

      INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                           evntlog_ord_id, evntlog_warehous_id, evntlog_number)
      SELECT DISTINCT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
                      NEW.cashrcpt_id, _whsId,
                     (_custNumber || '-' || NEW.cashrcpt_docnumber || ' ' || currConcat(NEW.cashrcpt_curr_id) || formatMoney(NEW.cashrcpt_amount))
      FROM evntnot, evnttype
      WHERE ((evntnot_evnttype_id=evnttype_id)
        AND  (evnttype_name=_evntType));
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._ccardtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  New.ccard_lastupdated := current_timestamp;
  New.ccard_last_updated_by_username := getEffectiveXtUser();

  IF (TG_OP = 'UPDATE') THEN
    INSERT INTO ccardaud
         VALUES (nextval('ccardaud_ccardaud_id_seq'), NEW.ccard_id,
                 OLD.ccard_seq, NEW.ccard_seq, OLD.ccard_cust_id, NEW.ccard_cust_id,
                 OLD.ccard_active, NEW.ccard_active, OLD.ccard_name, NEW.ccard_name,
                 OLD.ccard_address1, NEW.ccard_address1, OLD.ccard_address2,
                 NEW.ccard_address2, OLD.ccard_city, NEW.ccard_city, OLD.ccard_state,
                 NEW.ccard_state, OLD.ccard_zip, NEW.ccard_zip, OLD.ccard_country,
                 NEW.ccard_country, OLD.ccard_number, NEW.ccard_number, OLD.ccard_debit,
                 NEW.ccard_debit, OLD.ccard_month_expired, NEW.ccard_month_expired,
                 OLD.ccard_year_expired, NEW.ccard_year_expired, OLD.ccard_type, NEW.ccard_type);
  ELSE
-- We are inserting a record, therefore no old values
    INSERT INTO ccardaud
         VALUES (nextval('ccardaud_ccardaud_id_seq'), NEW.ccard_id,
                 NULL, NEW.ccard_seq, NULL, NEW.ccard_cust_id, NULL,
                 NEW.ccard_active, NULL, NEW.ccard_name, NULL,
                 NEW.ccard_address1, NULL, NEW.ccard_address2, NULL,
                 NEW.ccard_city, NULL, NEW.ccard_state, NULL,
                 NEW.ccard_zip, NULL, NEW.ccard_country, NULL,
                 NEW.ccard_number, NULL, NEW.ccard_debit, NULL,
                 NEW.ccard_month_expired, NULL, NEW.ccard_year_expired, NULL,
                 NEW.ccard_type);
  END IF;

  RETURN NEW;

END;

Function: public._charasshistorytrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF(TG_OP = 'DELETE') THEN
    IF (OLD.charass_target_type = 'INCDT') THEN
      INSERT INTO incdthist
            (incdthist_incdt_id, incdthist_descrip)
      VALUES(OLD.charass_target_id,
             ('Characteristic ' || 
               COALESCE((SELECT char_name 
                           FROM char
                          WHERE (char_id=OLD.charass_char_id)), '')
              || ' Deleted: "' || 
              COALESCE(OLD.charass_value,'')
              || '"') );
    END IF;
    RETURN OLD;
  ELSIF (NEW.charass_target_type = 'INCDT') THEN
    IF (TG_OP = 'INSERT') THEN
      INSERT INTO incdthist
            (incdthist_incdt_id, incdthist_descrip)
      VALUES(NEW.charass_target_id,
             ('Characteristic ' || 
               COALESCE((SELECT char_name 
                           FROM char
                          WHERE (char_id=NEW.charass_char_id)), '')
              || ' Added: "' || 
              COALESCE(NEW.charass_value,'')
              || '"') );
    ELSIF (TG_OP = 'UPDATE') THEN
      IF (COALESCE(NEW.charass_value,'') <> COALESCE(OLD.charass_value,'')) THEN
        INSERT INTO incdthist
              (incdthist_incdt_id, incdthist_descrip)
        VALUES(NEW.charass_target_id,
               ('Characteristic ' || 
                 COALESCE((SELECT char_name 
                             FROM char
                            WHERE (char_id=NEW.charass_char_id)), '')
                || ' Changed: "' || 
                COALESCE(OLD.charass_value,'')
                || '" -> "' ||
                COALESCE(NEW.charass_value,'')
                || '"') );
      END IF;
    END IF;
  END IF;
  RETURN NEW;
END;

Function: public._charasstrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NEW.charass_target_type = 'I' AND NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Items.';
   END IF;

   IF (NEW.charass_target_type = 'C' AND NOT checkPrivilege('MaintainCustomerMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Customers.';
   END IF;

-- Data check
  IF (NEW.charass_char_id IS NULL) THEN
	RAISE EXCEPTION 'You must supply a valid Characteristic ID.';
  END IF;

-- Default Logic
  IF (NEW.charass_default) THEN
    UPDATE charass
    SET charass_default = false 
    WHERE ((charass_target_id=NEW.charass_target_id)
    AND  (charass_target_type=NEW.charass_target_type)
    AND  (charass_char_id=NEW.charass_char_id)
    AND  (charass_id <> NEW.charass_ID));
  END IF;

-- Incident update
  IF (NEW.charass_target_type = 'INCDT') THEN
    UPDATE incdt SET incdt_updated = now() WHERE incdt_id = NEW.charass_target_id;
  END IF;
  
  RETURN NEW;
END;

Function: public._charbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainCharacteristics')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Characteristics.';
  END IF;

  RETURN NEW;
END;

Function: public._charopttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainCharacteristics')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Characteristic options.';
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    UPDATE charass SET
      charass_value = NEW.charopt_value
    WHERE ((charass_char_id=NEW.charopt_char_id)
      AND (charass_value=OLD.charopt_value));
  END IF;

  IF (TG_OP = 'DELETE') THEN
    IF (SELECT (count(charass_id) > 0)
        FROM charass
        WHERE ((charass_char_id=OLD.charopt_char_id)
         AND (charass_value=OLD.charopt_value))) THEN
       RAISE EXCEPTION 'This characteristic option value is in use and can not be deleted.';
    END IF;
  END IF;
  
  RETURN NEW;
END;

Function: public._checkheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE 
  _amount NUMERIC;
  _currrate NUMERIC;

BEGIN

-- get the base exchange rate for the check date
  IF (TG_OP = 'INSERT' AND NEW.checkhead_curr_rate IS NULL) THEN
    SELECT curr_rate INTO _currrate
    FROM curr_rate
    WHERE ( (NEW.checkhead_curr_id=curr_id)
      AND ( NEW.checkhead_checkdate BETWEEN curr_effective 
                                   AND curr_expires) );
    IF (FOUND) THEN
      NEW.checkhead_curr_rate := _currrate;
    ELSE
      RAISE EXCEPTION 'Currency exchange rate not found';
    END IF;
  END IF;

  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
    IF (NOT EXISTS (SELECT checkrecip_id
		    FROM checkrecip
		    WHERE ((checkrecip_type=NEW.checkhead_recip_type)
		      AND  (checkrecip_id=NEW.checkhead_recip_id)) )) THEN
      RAISE EXCEPTION 'Cannot verify recipient for check % (type %  id %)',
		      NEW.checkhead_number, NEW.checkhead_recip_type,
		      NEW.checkhead_recip_id;
    END IF;

    IF (NEW.checkhead_journalnumber IS NOT NULL
        AND NOT EXISTS (SELECT jrnluse_number
			FROM jrnluse
			WHERE (jrnluse_number=NEW.checkhead_journalnumber))
	) THEN
      RAISE EXCEPTION 'Journal Number % does not exist and cannot be used for check %.',
		      NEW.checkhead_journalnumber, NEW.checkhead_number;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._cmheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check BOOLEAN;
  _id INTEGER;
BEGIN
  -- Checks
  -- Start with privileges
  SELECT checkPrivilege('MaintainCreditMemos') INTO _check;
  IF ( (TG_OP = 'INSERT') OR (TG_OP = 'DELETE') ) THEN
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to maintain Credit Memos.';
    END IF;
  END IF;
  IF (TG_OP = 'UPDATE') THEN
    IF ((OLD.cmhead_printed = NEW.cmhead_printed) AND NOT (_check) ) THEN
      RAISE EXCEPTION 'You do not have privileges to maintain Credit Memos.';
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    DELETE FROM cmheadtax
    WHERE (taxhist_parent_id=OLD.cmhead_id);

    RETURN OLD;
  END IF;

  IF ( (NEW.cmhead_number IS NULL) OR (LENGTH(NEW.cmhead_number) = 0) ) THEN
    RAISE EXCEPTION 'You must enter a valid Memo # for this Credit Memo.';
  END IF;

  IF (TG_OP = 'INSERT') THEN
    SELECT cmhead_id INTO _id
    FROM cmhead
    WHERE (cmhead_number=NEW.cmhead_number);
    IF (FOUND) THEN
      RAISE EXCEPTION 'The Memo # is already in use.';
    END IF;

    IF (fetchMetricText('CMNumberGeneration') IN ('A','O')) THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('CmNumber', NEW.cmhead_number);
    ELSIF (fetchMetricText('CMNumberGeneration') = 'S') THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('SoNumber', NEW.cmhead_number);
    END IF;
  END IF;

  IF (NEW.cmhead_cust_id IS NOT NULL) THEN
    SELECT cust_id INTO _id
    FROM custinfo
    WHERE (cust_id=NEW.cmhead_cust_id);
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'You must enter a valid Customer # for this Credit Memo.';
    END IF;
  END IF;

  IF ( (NEW.cmhead_misc > 0) AND (NEW.cmhead_misc_accnt_id = -1) ) THEN
    RAISE EXCEPTION 'You may not enter a Misc. Charge without indicating the G/L Sales Account.';
  END IF;

  RETURN NEW;
END;

Function: public._cmheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    -- If this was created by a return, then reset the return
    IF (OLD.cmhead_rahead_id IS NOT NULL) THEN
      UPDATE rahead SET
        rahead_headcredited=false
      WHERE (rahead_id=OLD.cmhead_rahead_id);
      DELETE FROM rahist
      WHERE ((rahist_rahead_id=OLD.cmhead_rahead_id)
      AND (rahist_source='CM')
      AND (rahist_source_id=OLD.cmhead_id));
    END IF;
    RETURN OLD;
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Freight Tax
    IF (NEW.cmhead_freight <> 0) THEN
      PERFORM calculateTaxHist( 'cmheadtax',
                                NEW.cmhead_id,
                                NEW.cmhead_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.cmhead_docdate,
                                NEW.cmhead_curr_id,
                                NEW.cmhead_freight * -1 );
    END IF;
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

    IF ( (NEW.cmhead_freight <> OLD.cmhead_freight) OR
         (COALESCE(NEW.cmhead_taxzone_id,-1) <> COALESCE(OLD.cmhead_taxzone_id,-1)) OR
         (NEW.cmhead_docdate <> OLD.cmhead_docdate) OR
         (NEW.cmhead_curr_id <> OLD.cmhead_curr_id) ) THEN
  -- Calculate cmhead Tax
      PERFORM calculateTaxHist( 'cmheadtax',
                                NEW.cmhead_id,
                                NEW.cmhead_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.cmhead_docdate,
                                NEW.cmhead_curr_id,
                                NEW.cmhead_freight * -1 );
    END IF;

    IF ( (COALESCE(NEW.cmhead_taxzone_id,-1) <> COALESCE(OLD.cmhead_taxzone_id,-1)) OR
         (NEW.cmhead_docdate <> OLD.cmhead_docdate) OR
         (NEW.cmhead_curr_id <> OLD.cmhead_curr_id) ) THEN
  -- Calculate cmitem Tax
      IF (COALESCE(NEW.cmhead_taxzone_id,-1) <> COALESCE(OLD.cmhead_taxzone_id,-1)) THEN
    -- Cmitem trigger will calculate tax
        UPDATE cmitem SET cmitem_taxtype_id=getItemTaxType(itemsite_item_id,NEW.cmhead_taxzone_id)
        FROM itemsite 
        WHERE ((itemsite_id=cmitem_itemsite_id)
          AND (cmitem_cmhead_id=NEW.cmhead_id));
      ELSE
        PERFORM calculateTaxHist( 'cmitemtax',
                                  cmitem_id,
                                  NEW.cmhead_taxzone_id,
                                  cmitem_taxtype_id,
                                  NEW.cmhead_docdate,
                                  NEW.cmhead_curr_id,
                                  (cmitem_qtycredit * cmitem_qty_invuomratio) *
                                  (cmitem_unitprice / cmitem_price_invuomratio) * -1)
        FROM cmitem
        WHERE (cmitem_cmhead_id = NEW.cmhead_id);
      END IF;
    END IF;

  END IF;


  RETURN NEW;
END;

Function: public._cmitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check BOOLEAN;
  _id INTEGER;
BEGIN
  -- Checks
  -- Start with privileges
  SELECT checkPrivilege('MaintainCreditMemos') INTO _check;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Credit Memos.';
  END IF;

  IF (TG_OP = 'DELETE') THEN
    DELETE FROM cmitemtax
    WHERE (taxhist_parent_id=OLD.cmitem_id);

    RETURN OLD;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    IF ( (NEW.cmitem_qtycredit IS NULL) OR (NEW.cmitem_qtycredit = 0) ) THEN
      RAISE EXCEPTION 'Quantity to Credit must be greater than zero.';
    END IF;
    SELECT cmitem_id INTO _id
    FROM cmitem
    WHERE ( (cmitem_cmhead_id=NEW.cmitem_cmhead_id) AND (cmitem_linenumber=NEW.cmitem_linenumber) );
    IF (FOUND) THEN
      RAISE EXCEPTION 'The Memo Line Number is already in use.';
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._cmitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _ext NUMERIC;
  _r RECORD;

BEGIN
  IF (TG_OP = 'DELETE') THEN

--  If this was created by a return, reset return values
    IF (OLD.cmitem_raitem_id) IS NOT NULL THEN
      _ext := ROUND((OLD.cmitem_qtycredit * OLD.cmitem_qty_invuomratio) *  (OLD.cmitem_unitprice / OLD.cmitem_price_invuomratio),2);
      UPDATE raitem SET
        raitem_status = 'O',
        raitem_qtycredited = raitem_qtycredited-OLD.cmitem_qtycredit,
        raitem_amtcredited = raitem_amtcredited-_ext
      WHERE (raitem_id=OLD.cmitem_raitem_id);
    END IF;
    RETURN OLD;
  END IF;

-- Cache Credit Memo Head
  SELECT * INTO _r
  FROM cmhead
  WHERE (cmhead_id=NEW.cmitem_cmhead_id);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Credit Memo head not found';
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Tax
      PERFORM calculateTaxHist( 'cmitemtax',
                                NEW.cmitem_id,
                                COALESCE(_r.cmhead_taxzone_id, -1),
                                NEW.cmitem_taxtype_id,
                                COALESCE(_r.cmhead_docdate, CURRENT_DATE),
                                COALESCE(_r.cmhead_curr_id, -1),
                                (NEW.cmitem_qtycredit * NEW.cmitem_qty_invuomratio) *
                                (NEW.cmitem_unitprice / NEW.cmitem_price_invuomratio) * -1);
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

  -- Calculate Tax
    IF ( (NEW.cmitem_qtycredit <> OLD.cmitem_qtycredit) OR
         (NEW.cmitem_qty_invuomratio <> OLD.cmitem_qty_invuomratio) OR
         (NEW.cmitem_unitprice <> OLD.cmitem_unitprice) OR
         (NEW.cmitem_price_invuomratio <> OLD.cmitem_price_invuomratio) OR
         (COALESCE(NEW.cmitem_taxtype_id, -1) <> COALESCE(OLD.cmitem_taxtype_id, -1)) ) THEN
      PERFORM calculateTaxHist( 'cmitemtax',
                                NEW.cmitem_id,
                                COALESCE(_r.cmhead_taxzone_id, -1),
                                NEW.cmitem_taxtype_id,
                                COALESCE(_r.cmhead_docdate, CURRENT_DATE),
                                COALESCE(_r.cmhead_curr_id, -1),
                                (NEW.cmitem_qtycredit * NEW.cmitem_qty_invuomratio) *
                                (NEW.cmitem_unitprice / NEW.cmitem_price_invuomratio) * -1);
    END IF;
  END IF;


  RETURN NEW;
END;

Function: public._cntcttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  NEW.cntct_name := formatCntctName(NULL, NEW.cntct_first_name, NEW.cntct_middle, NEW.cntct_last_name, NEW.cntct_suffix);
  NEW.cntct_email := lower(NEW.cntct_email);

  IF (TG_OP = 'INSERT') THEN
    --- clear the number from the issue cache
    PERFORM clearNumberIssue('ContactNumber', NEW.cntct_number);
  END IF;
  
  RETURN NEW;
END;

Function: public._cntcttriggerafter()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cntctemlid INTEGER;
  _rows INTEGER;
BEGIN
  IF (TG_OP = 'INSERT') THEN
    IF(length(coalesce(NEW.cntct_email,'')) > 0) THEN
      INSERT INTO cntcteml (
        cntcteml_cntct_id, cntcteml_primary, cntcteml_email )
      VALUES (
        NEW.cntct_id, true, NEW.cntct_email );
    END IF;
    PERFORM postComment('ChangeLog', 'T', NEW.cntct_id,
                        ('Created by ' || getEffectiveXtUser()));
  ELSIF (TG_OP = 'UPDATE') THEN
    IF (OLD.cntct_email != NEW.cntct_email) THEN
      SELECT cntcteml_id INTO _cntctemlid
      FROM cntcteml
      WHERE ((cntcteml_cntct_id=NEW.cntct_id)
        AND (cntcteml_email=NEW.cntct_email));

      GET DIAGNOSTICS _rows = ROW_COUNT;
      IF (_rows = 0) THEN
        UPDATE cntcteml SET
          cntcteml_primary=false
        WHERE ((cntcteml_cntct_id=NEW.cntct_id)
         AND (cntcteml_primary=true));
       
        INSERT INTO cntcteml (
          cntcteml_cntct_id, cntcteml_primary, cntcteml_email )
        VALUES (
          NEW.cntct_id, true, NEW.cntct_email ); 
      ELSE
        UPDATE cntcteml SET
          cntcteml_primary=false
        WHERE ((cntcteml_cntct_id=NEW.cntct_id)
         AND (cntcteml_primary=true));

        UPDATE cntcteml SET
          cntcteml_primary=true
        WHERE (cntcteml_id=_cntctemlid);
      END IF;
    END IF;
  ELSIF (TG_OP = 'DELETE') THEN
      DELETE FROM comment
       WHERE (comment_source_id=OLD.cntct_id AND comment_source = 'T');
      DELETE FROM docass
       WHERE (docass_source_id=OLD.cntct_id AND docass_source_type = 'T')
          OR (docass_target_id=OLD.cntct_id AND docass_target_type = 'T');
      
      RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._cntcttriggerbeforedelete()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM cntctaddr WHERE cntctaddr_cntct_id=OLD.cntct_id;
    DELETE FROM cntctdata WHERE cntctdata_cntct_id=OLD.cntct_id;
    DELETE FROM cntcteml  WHERE cntcteml_cntct_id=OLD.cntct_id;

    -- these have denormalized cntct info so it should be ok to update them
    UPDATE cohead SET cohead_billto_cntct_id=NULL
     WHERE cohead_billto_cntct_id=OLD.cntct_id;
    UPDATE cohead SET cohead_shipto_cntct_id=NULL
     WHERE cohead_shipto_cntct_id=OLD.cntct_id;

    UPDATE pohead SET pohead_vend_cntct_id=NULL
     WHERE pohead_vend_cntct_id=OLD.cntct_id;
    UPDATE pohead SET pohead_shipto_cntct_id=NULL
     WHERE pohead_shipto_cntct_id=OLD.cntct_id;

    UPDATE quhead SET quhead_billto_cntct_id=NULL
     WHERE quhead_billto_cntct_id=OLD.cntct_id;
    UPDATE quhead SET quhead_shipto_cntct_id=NULL
     WHERE quhead_shipto_cntct_id=OLD.cntct_id;

    IF (fetchMetricBool('MultiWhs')) THEN
      UPDATE tohead SET tohead_destcntct_id=NULL
       WHERE tohead_destcntct_id=OLD.cntct_id;
      UPDATE tohead SET tohead_srccntct_id=NULL
       WHERE tohead_srccntct_id=OLD.cntct_id;
    END IF;

  END IF;
  RETURN OLD;
END;

Function: public._cntsliptrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _p RECORD;
  _comments TEXT;
  _temp TEXT;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    SELECT itemsite_loccntrl, itemsite_controlmethod,
           cntslip_posted, cntslip_lotserial, cntslip_comments,
           cntslip_number, cntslip_qty INTO _p
      FROM cntslip, invcnt, itemsite
     WHERE ( (cntslip_cnttag_id=invcnt_id)
       AND   (invcnt_itemsite_id=itemsite_id)
       AND   (cntslip_id=OLD.cntslip_id) );

    IF(_p.cntslip_posted) THEN
      SELECT ( '
Count Slip #' || _p.cntslip_number ||
             ' deleted ' || formatQty(_p.cntslip_qty) ) INTO _comments;

--  Add the Location name if the itemsite is MLC
      IF (_p.itemsite_loccntrl) THEN
        SELECT ( ', Location:' || location_name ) INTO _temp
          FROM location, cntslip
         WHERE ( (cntslip_location_id=location_id)
           AND   (cntslip_id=OLD.cntslip_id) );
  
        _comments := (_comments || _temp);
      END IF;
  
--  Add the Lot/Serial if the itemsite is Lot or Serial controlled
      IF (_p.itemsite_controlmethod = 'L') THEN
        _comments := (_comments || ( ', Lot #:' || _p.cntslip_lotserial));
      ELSIF (_p.itemsite_controlmethod = 'S') THEN
        _comments := (_comments || ( ', Serial #:' || _p.cntslip_lotserial));
      END IF;
  
      _comments := (_comments || ' ' || _p.cntslip_comments);
  
      UPDATE invcnt
         SET invcnt_qoh_after = ( COALESCE(invcnt_qoh_after, 0) - cntslip_qty),
             invcnt_comments = (invcnt_comments || _comments)
        FROM cntslip
       WHERE ( (cntslip_cnttag_id=invcnt_id)
         AND   (NOT invcnt_posted)
         AND   (cntslip_id=OLD.cntslip_id) );

    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._cobillbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM cobilltax
    WHERE (taxhist_parent_id=OLD.cobill_id);

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._cobilltrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

-- Cache Billing Head
  SELECT * INTO _r
  FROM cobmisc
  WHERE (cobmisc_id=NEW.cobill_cobmisc_id);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Billing head not found';
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Tax
      PERFORM calculateTaxHist( 'cobilltax',
                                NEW.cobill_id,
                                COALESCE(_r.cobmisc_taxzone_id, -1),
                                NEW.cobill_taxtype_id,
                                COALESCE(_r.cobmisc_shipdate, CURRENT_DATE),
                                COALESCE(_r.cobmisc_curr_id, -1),
                                (NEW.cobill_qty * coitem_qty_invuomratio) *
                                (coitem_price / coitem_price_invuomratio) )
      FROM coitem
      WHERE (coitem_id=NEW.cobill_coitem_id);
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

  -- Calculate Tax
    IF ( (NEW.cobill_qty <> OLD.cobill_qty) OR
         (NEW.cobill_taxtype_id <> OLD.cobill_taxtype_id) ) THEN
      PERFORM calculateTaxHist( 'cobilltax',
                                NEW.cobill_id,
                                COALESCE(_r.cobmisc_taxzone_id, -1),
                                NEW.cobill_taxtype_id,
                                COALESCE(_r.cobmisc_shipdate, CURRENT_DATE),
                                COALESCE(_r.cobmisc_curr_id, -1),
                                (NEW.cobill_qty * coitem_qty_invuomratio) *
                                (coitem_price / coitem_price_invuomratio) )
      FROM coitem
      WHERE (coitem_id=NEW.cobill_coitem_id);
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._cobmiscbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM cobmisctax
    WHERE (taxhist_parent_id=OLD.cobmisc_id);

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._cobmisctrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    -- Something can go here
    RETURN OLD;
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Freight Tax
    IF (NEW.cobmisc_freight <> 0) THEN
      PERFORM calculateTaxHist( 'cobmisctax',
                                NEW.cobmisc_id,
                                NEW.cobmisc_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.cobmisc_invcdate,
                                NEW.cobmisc_curr_id,
                                NEW.cobmisc_freight );
    END IF;
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

  -- Calculate Tax
    IF (COALESCE(NEW.cobmisc_taxzone_id,-1) <> COALESCE(OLD.cobmisc_taxzone_id,-1)) THEN
      UPDATE cobill SET cobill_taxtype_id=getItemTaxType(itemsite_item_id,NEW.cobmisc_taxzone_id)
      FROM coitem
        JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
      WHERE ((coitem_id=cobill_coitem_id)
       AND (cobill_cobmisc_id=NEW.cobmisc_id));
    END IF;
    
    IF ( (NEW.cobmisc_freight <> OLD.cobmisc_freight) OR
         (COALESCE(NEW.cobmisc_taxzone_id,-1) <> COALESCE(OLD.cobmisc_taxzone_id,-1)) OR
         (NEW.cobmisc_invcdate <> OLD.cobmisc_invcdate) OR
         (NEW.cobmisc_curr_id <> OLD.cobmisc_curr_id) ) THEN
      PERFORM calculateTaxHist( 'cobmisctax',
                                NEW.cobmisc_id,
                                NEW.cobmisc_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.cobmisc_invcdate,
                                NEW.cobmisc_curr_id,
                                NEW.cobmisc_freight );
      PERFORM calculateTaxHist( 'cobilltax',
                                cobill_id,
                                NEW.cobmisc_taxzone_id,
                                cobill_taxtype_id,
                                NEW.cobmisc_invcdate,
                                NEW.cobmisc_curr_id,
                                (cobill_qty * coitem_qty_invuomratio) *
                                (coitem_price / coitem_price_invuomratio) )
      FROM cobill JOIN coitem ON (coitem_id = cobill_coitem_id)
      WHERE (cobill_cobmisc_id = NEW.cobmisc_id);
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._commenttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NEW.comment_cmnttype_id IS NULL) THEN
	RAISE EXCEPTION 'You must supply a valid Comment Type ID.';
  ELSIF (NEW.comment_source = 'INCDT') THEN
    UPDATE incdt SET incdt_updated = now() WHERE incdt_id = NEW.comment_source_id;
  END IF;

  RETURN NEW;
END;

Function: public._companytrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _used	BOOLEAN := false;

BEGIN
  IF (NEW.company_external AND NOT OLD.company_external) THEN
    IF EXISTS(SELECT accnt_id
              FROM accnt, company, (
                  SELECT DISTINCT apaccnt_ap_accnt_id AS test_accnt_id FROM apaccnt
                  UNION SELECT DISTINCT apaccnt_discount_accnt_id FROM apaccnt
                  UNION SELECT DISTINCT apaccnt_prepaid_accnt_id FROM apaccnt
                  UNION SELECT DISTINCT apopen_accnt_id FROM apopen
                  UNION SELECT DISTINCT araccnt_ar_accnt_id FROM araccnt
                  UNION SELECT DISTINCT araccnt_deferred_accnt_id FROM araccnt
                  UNION SELECT DISTINCT araccnt_freight_accnt_id FROM araccnt
                  UNION SELECT DISTINCT araccnt_prepaid_accnt_id FROM araccnt
                  UNION SELECT DISTINCT aropen_accnt_id FROM aropen
                  UNION SELECT DISTINCT bankaccnt_accnt_id FROM bankaccnt
                  UNION SELECT DISTINCT bankaccnt_rec_accnt_id FROM bankaccnt
                  UNION SELECT DISTINCT budgitem_accnt_id FROM budgitem
                  UNION SELECT DISTINCT cashrcptmisc_accnt_id FROM cashrcptmisc
                  UNION SELECT DISTINCT cmhead_misc_accnt_id FROM cmhead
                  UNION SELECT DISTINCT cobmisc_misc_accnt_id FROM cobmisc
                  UNION SELECT DISTINCT cohead_misc_accnt_id FROM cohead
                  UNION SELECT DISTINCT coitem_cos_accnt_id FROM coitem
                  UNION SELECT DISTINCT costcat_adjustment_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_asset_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_freight_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_invcost_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_laboroverhead_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_liability_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_matusage_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_mfgscrap_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_purchprice_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_scrap_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_shipasset_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_toliability_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_transform_accnt_id FROM costcat
                  UNION SELECT DISTINCT costcat_wip_accnt_id FROM costcat
                  UNION SELECT DISTINCT costelem_exp_accnt_id FROM costelem
                  UNION SELECT DISTINCT expcat_exp_accnt_id FROM expcat
                  UNION SELECT DISTINCT expcat_freight_accnt_id FROM expcat
                  UNION SELECT DISTINCT expcat_liability_accnt_id FROM expcat
                  UNION SELECT DISTINCT expcat_purchprice_accnt_id FROM expcat
                  UNION SELECT DISTINCT glseries_accnt_id FROM glseries
                  UNION SELECT DISTINCT gltrans_accnt_id FROM gltrans
                  UNION SELECT DISTINCT invchead_misc_accnt_id FROM invchead
                  UNION SELECT DISTINCT quhead_misc_accnt_id FROM quhead
                  UNION SELECT DISTINCT salesaccnt_cor_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salesaccnt_cos_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salesaccnt_cow_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salesaccnt_credit_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salesaccnt_returns_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salesaccnt_sales_accnt_id FROM salesaccnt
                  UNION SELECT DISTINCT salescat_ar_accnt_id FROM salescat
                  UNION SELECT DISTINCT salescat_prepaid_accnt_id FROM salescat
                  UNION SELECT DISTINCT salescat_sales_accnt_id FROM salescat
                  UNION SELECT DISTINCT stdjrnlitem_accnt_id FROM stdjrnlitem
                  UNION SELECT DISTINCT tax_sales_accnt_id FROM tax
                  UNION SELECT DISTINCT taxauth_accnt_id FROM taxauth
                  UNION SELECT DISTINCT vodist_accnt_id FROM vodist
                  UNION SELECT DISTINCT warehous_default_accnt_id FROM whsinfo
                ) AS dummy
              WHERE ((accnt_id=test_accnt_id)
                AND  (accnt_company=company_number)
                AND  (accnt_company=NEW.company_number))
    ) THEN
      RAISE EXCEPTION 'Cannot make Company % External because it is used in the local database.',
                      NEW.company_number;
    ELSIF (fetchMetricBool('EnableReturnAuth')) THEN
      IF EXISTS(SELECT accnt_id
              FROM accnt, company, (
                  SELECT DISTINCT rahead_misc_accnt_id AS test_accnt_id FROM rahead
                  UNION SELECT DISTINCT raitem_cos_accnt_id FROM raitem
                ) AS dummy
              WHERE ((accnt_id=test_accnt_id)
                AND  (accnt_company=company_number)
                AND  (accnt_company=NEW.company_number))
      ) THEN
        RAISE EXCEPTION 'Cannot make Company % External because it is used in the local database.',
                        NEW.company_number;
      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._crmacctaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _gotpriv    BOOLEAN;

BEGIN
  /* update _number and _name separately to propagate just what changed.
     the priv manipulation allows targeted updates of crmaccount-maintained data
     (note: grantPriv() == false if the user already had the priv, true if this
     call granted the priv).
   */
  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
    IF (NEW.crmacct_cust_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainCustomerMasters');
      UPDATE custinfo SET cust_number = NEW.crmacct_number
      WHERE ((cust_id=NEW.crmacct_cust_id)
        AND  (cust_number!=NEW.crmacct_number));
      UPDATE custinfo SET cust_name = NEW.crmacct_name
      WHERE ((cust_id=NEW.crmacct_cust_id)
        AND  (cust_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainCustomerMasters');
      END IF;
    END IF;

    IF (NEW.crmacct_emp_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainEmployees');
      UPDATE emp SET emp_code = NEW.crmacct_number
      WHERE ((emp_id=NEW.crmacct_emp_id)
        AND  (emp_code!=NEW.crmacct_number));
      UPDATE emp SET emp_name = NEW.crmacct_name
      WHERE ((emp_id=NEW.crmacct_emp_id)
        AND  (emp_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainEmployees');
      END IF;
    END IF;

    IF (NEW.crmacct_prospect_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainProspectMasters');
      UPDATE prospect SET prospect_number = NEW.crmacct_number
      WHERE ((prospect_id=NEW.crmacct_prospect_id)
        AND  (prospect_number!=NEW.crmacct_number));
      UPDATE prospect SET prospect_name = NEW.crmacct_name
      WHERE ((prospect_id=NEW.crmacct_prospect_id)
        AND  (prospect_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainProspectMasters');
      END IF;
    END IF;

    IF (NEW.crmacct_salesrep_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainSalesReps');
      UPDATE salesrep SET salesrep_number = NEW.crmacct_number
      WHERE ((salesrep_id=NEW.crmacct_salesrep_id)
        AND  (salesrep_number!=NEW.crmacct_number));
      UPDATE salesrep SET salesrep_name = NEW.crmacct_name
      WHERE ((salesrep_id=NEW.crmacct_salesrep_id)
        AND  (salesrep_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainSalesReps');
      END IF;
    END IF;

    IF (NEW.crmacct_taxauth_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainTaxAuthorities');
      UPDATE taxauth SET taxauth_code = NEW.crmacct_number
      WHERE ((taxauth_id=NEW.crmacct_taxauth_id)
        AND  (taxauth_code!=NEW.crmacct_number));
      UPDATE taxauth SET taxauth_name = NEW.crmacct_name
      WHERE ((taxauth_id=NEW.crmacct_taxauth_id)
        AND  (taxauth_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainTaxAuthorities');
      END IF;
    END IF;

    IF (NEW.crmacct_vend_id IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainVendors');
      UPDATE vendinfo SET vend_number = NEW.crmacct_number
      WHERE ((vend_id=NEW.crmacct_vend_id)
        AND  (vend_number!=NEW.crmacct_number));
      UPDATE vendinfo SET vend_name = NEW.crmacct_name
      WHERE ((vend_id=NEW.crmacct_vend_id)
        AND  (vend_name!=NEW.crmacct_name));
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainVendors');
      END IF;
    END IF;

    -- Link Primary and Secondary Contacts to this Account if they are not already
    IF (NEW.crmacct_cntct_id_1 IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainAllContacts');
      UPDATE cntct SET cntct_crmacct_id = NEW.crmacct_id
       WHERE cntct_id=NEW.crmacct_cntct_id_1;
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainAllContacts');
      END IF;
    END IF;

    IF (NEW.crmacct_cntct_id_2 IS NOT NULL) THEN
      _gotpriv := grantPriv(getEffectiveXtUser(), 'MaintainAllContacts');
      UPDATE cntct SET cntct_crmacct_id = NEW.crmacct_id
       WHERE cntct_id=NEW.crmacct_cntct_id_2;
      IF (_gotpriv) THEN
        PERFORM revokePriv(getEffectiveXtUser(), 'MaintainAllContacts');
      END IF;
    END IF;

    -- cannot have fkey references to system catalogs so enforce them here
    IF (NEW.crmacct_usr_username IS NOT NULL) THEN
      IF (NOT EXISTS(SELECT usename
                       FROM pg_user
                      WHERE usename=NEW.crmacct_usr_username)) THEN
        RAISE EXCEPTION 'User % does not exist so this CRM Account Number is invalid.',
                        NEW.crmacct_usr_username;
      END IF;
      IF (TG_OP = 'UPDATE') THEN
        -- reminder: this evaluates to false if either is NULL
        IF (NEW.crmacct_usr_username != OLD.crmacct_usr_username) THEN
          RAISE EXCEPTION 'Cannot change the user name for %',
                          OLD.crmacct_usr_username;
        END IF;
      END IF;
      UPDATE usrpref SET usrpref_value = NEW.crmacct_name
      WHERE ((usrpref_username=NEW.crmacct_usr_username)
        AND  (usrpref_name='propername')
        AND  (usrpref_value!=NEW.crmacct_name));
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    IF (OLD.crmacct_cust_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a Customer [xtuple: deleteCrmAccount, -1]';
    END IF;

    IF (OLD.crmacct_emp_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is an Employee [xtuple: deleteCrmAccount, -7]';
    END IF;

    IF (OLD.crmacct_prospect_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a Prospect [xtuple: deleteCrmAccount, -3]';
    END IF;

    DELETE FROM salesrep WHERE salesrep_id  = OLD.crmacct_salesrep_id;
    IF (OLD.crmacct_salesrep_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a Sales Rep [xtuple: deleteCrmAccount, -6]';
    END IF;

    IF (OLD.crmacct_taxauth_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a Tax Authority [xtuple: deleteCrmAccount, -5]';
    END IF;

    IF (EXISTS(SELECT usename
                 FROM pg_user
                WHERE usename=OLD.crmacct_usr_username)) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a User [xtuple: deleteCrmAccount, -8]';
    END IF;

    IF (OLD.crmacct_vend_id IS NOT NULL) THEN
      RAISE EXCEPTION 'Cannot delete CRM Account because it is a Vendor [xtuple: deleteCrmAccount, -2]';
    END IF;

    DELETE FROM imageass
     WHERE (imageass_source_id=OLD.crmacct_id) AND (imageass_source='CRMA');
    DELETE FROM url
     WHERE (url_source_id=OLD.crmacct_id)      AND (url_source='CRMA');

  END IF;

  SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
   WHERE (cmnttype_name='ChangeLog');
  IF (_cmnttypeid IS NOT NULL) THEN
    IF (TG_OP = 'INSERT') THEN
      PERFORM postComment(_cmnttypeid, 'CRMA', NEW.crmacct_id,
                          ('Created by ' || getEffectiveXtUser()));

    ELSIF (TG_OP = 'DELETE') THEN
      PERFORM postComment(_cmnttypeid, 'CRMA', OLD.crmacct_id,
                          'Deleted "' || OLD.crmacct_number || '"');
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._crmacctbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _count        INTEGER;
BEGIN
  -- disallow reusing crmacct_numbers
  IF (TG_OP IN ('INSERT', 'UPDATE')) THEN
    IF (TG_OP = 'INSERT' AND fetchMetricText('CRMAccountNumberGeneration') IN ('A','O')) THEN
      PERFORM clearNumberIssue('CRMAccountNumber', NEW.crmacct_number);
    END IF;

    NEW.crmacct_usr_username := LOWER(TRIM(NEW.crmacct_usr_username));
    IF (NEW.crmacct_usr_username = '') THEN
      NEW.crmacct_usr_username = NULL;
    END IF;

    NEW.crmacct_owner_username := LOWER(TRIM(NEW.crmacct_owner_username));
    IF (COALESCE(NEW.crmacct_owner_username, '') = '') THEN
      NEW.crmacct_owner_username = getEffectiveXtUser();
    END IF;

    IF (NEW.crmacct_competitor_id < 0) THEN
      NEW.crmacct_competitor_id := NULL;
    END IF;
    IF (NEW.crmacct_partner_id < 0) THEN
      NEW.crmacct_partner_id := NULL;
    END IF;

    NEW.crmacct_number = UPPER(NEW.crmacct_number);

    IF (TG_OP = 'UPDATE') THEN
      -- TODO: why not ALTER USER OLD.crmacct_number RENAME TO LOWER(NEW.crmacct_number)?
      IF (NEW.crmacct_number != UPPER(OLD.crmacct_number) AND
          NEW.crmacct_usr_username IS NOT NULL            AND
          UPPER(NEW.crmacct_usr_username) != NEW.crmacct_number) THEN
        RAISE EXCEPTION 'The CRM Account % is associated with a system User so the number cannot be changed.',
                        NEW.crmacct_number;
      END IF;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    UPDATE cntct SET cntct_crmacct_id = NULL
     WHERE cntct_crmacct_id = OLD.crmacct_id;

    GET DIAGNOSTICS _count = ROW_COUNT;
    RAISE DEBUG 'updated % contacts', _count;

    RETURN OLD;

  END IF;

  RETURN NEW;
END;

Function: public._custaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _whsId      INTEGER := -1;

BEGIN

  IF (TG_OP = 'INSERT') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_cust_id=NEW.cust_id,
                         crmacct_name=NEW.cust_name,
                         crmacct_prospect_id=NULL
      WHERE crmacct_number=NEW.cust_number;
      IF (FOUND) THEN
        DELETE FROM prospect WHERE prospect_id=NEW.cust_id;
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,  crmacct_name,    crmacct_active,
                            crmacct_type,    crmacct_cust_id, crmacct_cntct_id_1,
                            crmacct_cntct_id_2
                  ) VALUES (NEW.cust_number, NEW.cust_name,   NEW.cust_active,
                            'O',             NEW.cust_id,     NEW.cust_cntct_id,
                            NEW.cust_corrcntct_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    PERFORM updateCharAssignment('C', NEW.cust_id, char_id, charass_value)
       FROM custtype
       JOIN charass ON (custtype_id=charass_target_id AND charass_target_type='CT')
       JOIN char ON (charass_char_id=char_id)
       WHERE ((custtype_id=NEW.cust_custtype_id)
          AND (custtype_char)
          AND (charass_default));

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.cust_number
    WHERE ((crmacct_cust_id=NEW.cust_id)
      AND  (crmacct_number!=NEW.cust_number));

    UPDATE crmacct SET crmacct_name = NEW.cust_name
    WHERE ((crmacct_cust_id=NEW.cust_id)
      AND  (crmacct_name!=NEW.cust_name));
  END IF;

  IF (TG_OP = 'INSERT') THEN
  -- find the warehouse for which to create evntlog entries
    SELECT usrpref_value  INTO _whsId
    FROM usrpref
    WHERE usrpref_username = getEffectiveXtUser()
      AND usrpref_name = 'PreferredWarehouse';

    INSERT INTO evntlog (evntlog_evnttime, evntlog_username,
                         evntlog_evnttype_id, evntlog_ordtype,
                         evntlog_ord_id, evntlog_warehous_id, evntlog_number)
    SELECT DISTINCT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
                    'C', NEW.cust_id, _whsId, NEW.cust_number
    FROM evntnot, evnttype
    WHERE ((evntnot_evnttype_id=evnttype_id)
      AND  (evnttype_name='NewCustomer'));
  END IF;

  IF (fetchMetricBool('CustomerChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN

        IF (OLD.cust_number <> NEW.cust_number) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.cust_id,
                              ('Number changed from "' || OLD.cust_number ||
                               '" to "' || NEW.cust_number || '"') );
        END IF;

        IF (OLD.cust_name <> NEW.cust_name) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.cust_id,
                              ('Name changed from "' || OLD.cust_name ||
                               '" to "' || NEW.cust_name || '"') );
        END IF;

        IF (OLD.cust_active <> NEW.cust_active) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              CASE WHEN NEW.cust_active THEN 'Activated'
                                   ELSE 'Deactivated' END);
        END IF;

        IF (OLD.cust_discntprcnt <> NEW.cust_discntprcnt) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Discount changed from "' ||
                               formatprcnt(OLD.cust_discntprcnt) || '%" to "' ||
                               formatprcnt(NEW.cust_discntprcnt) || '%"') );
        END IF;

        IF (OLD.cust_creditlmt <> NEW.cust_creditlmt) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Credit Limit changed from ' || formatMoney(OLD.cust_creditlmt) ||
                               ' to ' || formatMoney(NEW.cust_creditlmt)));
        END IF;

        IF (OLD.cust_creditstatus <> NEW.cust_creditstatus) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Credit Status Changed from "' ||
                               CASE OLD.cust_creditstatus
                                    WHEN 'G' THEN 'In Good Standing'
                                    WHEN 'W' THEN 'Credit Warning'
                                    WHEN 'H' THEN 'Credit Hold'
                                    ELSE 'Unknown/Error'
                               END || '" to "' ||
                               CASE NEW.cust_creditstatus
                                    WHEN 'G' THEN 'In Good Standing'
                                    WHEN 'W' THEN 'Credit Warning'
                                    WHEN 'H' THEN 'Credit Hold'
                                    ELSE 'Unknown/Error'
                               END || '"') );
        END IF;

        IF (OLD.cust_custtype_id <> NEW.cust_custtype_id) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Customer type changed from "' ||
                               (SELECT custtype_code FROM custtype
                                 WHERE custtype_id = OLD.cust_custtype_id) || '" to "' ||
                               (SELECT custtype_code FROM custtype
                                 WHERE custtype_id = NEW.cust_custtype_id) || '"') );
        END IF;

        IF (COALESCE(OLD.cust_gracedays,-1) <> COALESCE(NEW.cust_gracedays,-1)) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Grace Days changed from "' ||
                               COALESCE(TEXT(OLD.cust_gracedays), 'Default') ||
                               '" to "' ||
                               COALESCE(TEXT(NEW.cust_gracedays), 'Default') || '"'));
        END IF;

        IF (OLD.cust_terms_id <> NEW.cust_terms_id) THEN
          PERFORM postComment(_cmnttypeid, 'C', NEW.cust_id,
                              ('Terms changed from "' ||
                               (SELECT terms_code FROM terms
                                 WHERE terms_id = OLD.cust_terms_id) || '" to "' ||
                               (SELECT terms_code FROM terms
                                 WHERE terms_id = NEW.cust_terms_id) || '"'));
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._custinfoafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  -- handle transitory state when converting customer to prospect
  IF EXISTS(SELECT quhead_id
              FROM quhead
             WHERE (quhead_cust_id=OLD.cust_id) AND
     NOT EXISTS(SELECT prospect_id
                  FROM prospect
                 WHERE prospect_id=OLD.cust_id)) THEN
    RAISE EXCEPTION '[xtuple: deleteCustomer, -8]';
  END IF;

  IF EXISTS(SELECT invchead_id
              FROM invchead
             WHERE (invchead_cust_id=OLD.cust_id)) THEN
    RAISE EXCEPTION '[xtuple: deleteCustomer, -7]';
  END IF;
  -- end TODO

  IF EXISTS(SELECT checkhead_recip_id
              FROM checkhead
             WHERE ((checkhead_recip_id=OLD.cust_id)
               AND  (checkhead_recip_type='C'))) THEN
    RAISE EXCEPTION '[xtuple: deleteCustomer, -6]';
  END IF;

  DELETE FROM taxreg
   WHERE ((taxreg_rel_type='C')
     AND  (taxreg_rel_id=OLD.cust_id));

  DELETE FROM ipsass
   WHERE (ipsass_cust_id=OLD.cust_id);

  IF (fetchMetricBool('CustomerChangeLog')) THEN
    PERFORM postComment(cmnttype_id, 'C', OLD.cust_id,
                        ('Deleted "' || OLD.cust_number || '"'))
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');
  END IF;

  RETURN OLD;
END;

Function: public._custinfobeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF NOT (checkPrivilege('MaintainCustomerMasters')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Customers.';
  END IF;

  UPDATE crmacct SET crmacct_cust_id = NULL
   WHERE crmacct_cust_id = OLD.cust_id;

  RETURN OLD;
END;

Function: public._custtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF NOT (checkPrivilege('MaintainCustomerMasters') OR
          checkPrivilege('PostMiscInvoices')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Customers.';
  END IF;

  IF (NEW.cust_number IS NULL) THEN
        RAISE EXCEPTION 'You must supply a valid Customer Number.';
  END IF;

  IF (LENGTH(COALESCE(NEW.cust_name,''))=0) THEN
        RAISE EXCEPTION 'You must supply a valid Customer Name.';
  END IF;

  IF (NEW.cust_custtype_id IS NULL) THEN
        RAISE EXCEPTION 'You must supply a valid Customer Type ID.';
  END IF;

  IF (NEW.cust_salesrep_id IS NULL) THEN
        RAISE EXCEPTION 'You must supply a valid Sales Rep ID.';
  END IF;

  IF (NEW.cust_terms_id IS NULL) THEN
        RAISE EXCEPTION 'You must supply a valid Terms Code ID.';
  END IF;

  IF (TG_OP = 'INSERT' AND fetchMetricText('CRMAccountNumberGeneration') IN ('A','O')) THEN
    PERFORM clearNumberIssue('CRMAccountNumber', NEW.cust_number);
  END IF;

  NEW.cust_number := UPPER(NEW.cust_number);

  RETURN NEW;
END;

Function: public._custtypeafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (SELECT fetchMetricValue('DefaultCustType') = OLD.custtype_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Customer Type [xtuple: custtype, -1, %]',
                    OLD.custtype_code;
  END IF;

  RETURN OLD;
END;

Function: public._custtypetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _code       TEXT;

BEGIN

--  Checks
  IF (TG_OP IN ('INSERT','UPDATE')) THEN

    IF (LENGTH(COALESCE(NEW.custtype_code, ''))=0) THEN
      RAISE EXCEPTION 'You must supply a valid Customer Type Code.';
    END IF;

    SELECT custtype_code INTO _code
    FROM custtype
    WHERE ( (UPPER(custtype_code)=UPPER(NEW.custtype_code))
      AND (custtype_id<>NEW.custtype_id) );
    IF (FOUND) THEN
      RAISE EXCEPTION 'The Customer Type Code entered cannot be used as it is in use.';
    END IF;

  END IF;

  RETURN NEW;
END;

Function: public._docasstrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NEW.docass_source_type = 'INCDT') THEN
    UPDATE incdt SET incdt_updated = now() WHERE incdt_id = NEW.docass_source_id;
  END IF;

  RETURN NEW;
END;

Function: public._empafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (fetchMetricBool('EmployeeChangeLog')) THEN
    PERFORM postComment(cmnttype_id, 'EMP', OLD.emp_id,
                        ('Deleted "' || OLD.emp_code || '"'))
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');
  END IF;

  RETURN OLD;
END;

Function: public._empaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid     INTEGER;
  _newcrmacctname TEXT;

BEGIN

  IF (TG_OP = 'INSERT') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_emp_id=NEW.emp_id,
                         crmacct_name=NEW.emp_name
       WHERE crmacct_number=NEW.emp_code;
      IF (FOUND) THEN
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,  crmacct_name,    crmacct_active,
                            crmacct_type,    crmacct_emp_id,  crmacct_cntct_id_1
                  ) VALUES (NEW.emp_code,    NEW.emp_name,    NEW.emp_active, 
                            'I',             NEW.emp_id,      NEW.emp_cntct_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    /* TODO: default characteristic assignments based on empgrp? */

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.emp_code
    WHERE ((crmacct_emp_id=NEW.emp_id)
      AND  (crmacct_number!=NEW.emp_code));

    UPDATE crmacct SET crmacct_name = NEW.emp_name
    WHERE ((crmacct_emp_id=NEW.emp_id)
      AND  (crmacct_name!=NEW.emp_name));
  END IF;

  IF (fetchMetricBool('EmployeeChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN

        IF (OLD.emp_number <> NEW.emp_number) THEN
          PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id,
                              ('Number Changed from "' || OLD.emp_number ||
                               '" to "' || NEW.emp_number || '"'));
        END IF;

        IF (OLD.emp_code <> NEW.emp_code) THEN
          PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id,
                              ('Code Changed from "' || OLD.emp_code ||
                               '" to "' || NEW.emp_code || '"'));
        END IF;

        IF (OLD.emp_active <> NEW.emp_active) THEN
          PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id,
                              CASE WHEN NEW.emp_active THEN 'Activated'
                                   ELSE 'Deactivated' END);
        END IF;

        IF (COALESCE(OLD.emp_dept_id, -1) <> COALESCE(NEW.emp_dept_id, -1)) THEN
          PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id,
                              ('Department Changed from "' ||
                               COALESCE((SELECT dept_number FROM dept
                                          WHERE dept_id=OLD.emp_dept_id), '')
                               || '" to "' ||
                               COALESCE((SELECT dept_number FROM dept
                                          WHERE dept_id=NEW.emp_dept_id), '') || '"'));
        END IF;

        IF (COALESCE(OLD.emp_shift_id, -1) <> COALESCE(NEW.emp_shift_id, -1)) THEN
          PERFORM postComment(_cmnttypeid, 'EMP', NEW.emp_id,
                              ('Shift Changed from "' ||
                               COALESCE((SELECT shift_number FROM shift
                                          WHERE shift_id=OLD.emp_shift_id), '')
                               || '" to "' ||
                               COALESCE((SELECT shift_number FROM shift
                                          WHERE shift_id=NEW.emp_shift_id), '') || '"'));
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._empbeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF NOT (checkPrivilege('MaintainEmployees')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Employees.';
  END IF;

  UPDATE crmacct SET crmacct_emp_id = NULL
   WHERE crmacct_emp_id = OLD.emp_id;

  UPDATE salesrep SET salesrep_emp_id = NULL
   WHERE salesrep_emp_id = OLD.emp_id;

  RETURN OLD;
END;

Function: public._empbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  IF NOT (checkPrivilege('MaintainEmployees')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Employees.';
  END IF;

  IF (NEW.emp_code IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Employee Code.';
  END IF;

  IF (NEW.emp_number IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Employee Number.';
  END IF;

  IF (NEW.emp_id = NEW.emp_mgr_emp_id) THEN
    RAISE EXCEPTION 'An Employee may not be his or her own Manager.';
  END IF;

  -- ERROR:  cannot use column references in default expression
  IF (NEW.emp_name IS NULL) THEN
    NEW.emp_name = COALESCE(formatCntctName(NEW.emp_cntct_id), NEW.emp_number);
  END IF;

  IF (TG_OP = 'INSERT' AND fetchMetricText('CRMAccountNumberGeneration') IN ('A','O')) THEN
    PERFORM clearNumberIssue('CRMAccountNumber', NEW.emp_number);
  END IF;

  NEW.emp_code := UPPER(NEW.emp_code);

  -- deprecated column emp_username
  IF (TG_OP = 'UPDATE' AND
      LOWER(NEW.emp_username) != LOWER(NEW.emp_code) AND
      EXISTS(SELECT 1
               FROM crmacct
              WHERE crmacct_emp_id = NEW.emp_id
                AND crmacct_usr_username IS NOT NULL)) THEN
    NEW.emp_username = LOWER(NEW.emp_code);
  END IF;

  RETURN NEW;
END;

Function: public._gltransaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _externalCompany      BOOLEAN := false;
  _updated BOOLEAN := false;
BEGIN
  IF(TG_OP='DELETE') THEN
    RAISE EXCEPTION 'You may not delete G/L Transactions once they have been created.';
  ELSIF (TG_OP = 'UPDATE') THEN
    SELECT company_external INTO _externalCompany
    FROM company JOIN accnt ON (company_number=accnt_company)
    WHERE (accnt_id=NEW.gltrans_accnt_id);
    IF (_externalCompany) THEN
      RAISE EXCEPTION 'Transactions are not allowed for G/L Accounts with External Company segments.';
    END IF;

    IF(OLD.gltrans_id != NEW.gltrans_id) THEN
      _updated := true;
    ELSIF(OLD.gltrans_date != NEW.gltrans_date) THEN
      _updated := true;
    ELSIF(OLD.gltrans_accnt_id != NEW.gltrans_accnt_id) THEN
      _updated := true;
    ELSIF(OLD.gltrans_amount != NEW.gltrans_amount) THEN
      _updated := true;
    ELSIF(OLD.gltrans_username != NEW.gltrans_username) THEN
      _updated := true;
    ELSIF( (OLD.gltrans_sequence IS NULL     AND NEW.gltrans_sequence IS NOT NULL)
        OR (OLD.gltrans_sequence IS NOT NULL AND NEW.gltrans_sequence IS NULL)
        OR (COALESCE(OLD.gltrans_sequence,0) != COALESCE(NEW.gltrans_sequence,0)) ) THEN
      _updated := true;
    ELSIF( (OLD.gltrans_created IS NULL     AND NEW.gltrans_created IS NOT NULL)
        OR (OLD.gltrans_created IS NOT NULL AND NEW.gltrans_created IS NULL)
        OR (COALESCE(OLD.gltrans_created,now()) != COALESCE(NEW.gltrans_created,now())) ) THEN
      _updated := true;
    ELSIF( (OLD.gltrans_source IS NULL     AND NEW.gltrans_source IS NOT NULL)
        OR (OLD.gltrans_source IS NOT NULL AND NEW.gltrans_source IS NULL)
        OR (COALESCE(OLD.gltrans_source,'') != COALESCE(NEW.gltrans_source,'')) ) THEN
      _updated := true;
    ELSIF( (OLD.gltrans_docnumber IS NULL     AND NEW.gltrans_docnumber IS NOT NULL)
        OR (OLD.gltrans_docnumber IS NOT NULL AND NEW.gltrans_docnumber IS NULL)
        OR (COALESCE(OLD.gltrans_docnumber,'') != COALESCE(NEW.gltrans_docnumber,'')) ) THEN
      _updated := true;
    ELSIF( (OLD.gltrans_doctype IS NULL     AND NEW.gltrans_doctype IS NOT NULL)
        OR (OLD.gltrans_doctype IS NOT NULL AND NEW.gltrans_doctype IS NULL)
        OR (COALESCE(OLD.gltrans_doctype,'') != COALESCE(NEW.gltrans_doctype,'')) ) THEN
      _updated := true;
    END IF;

    IF(_updated) THEN
      RAISE EXCEPTION 'You may not alter some G/L Transaction fields once they have been created.';
    END IF;
  ELSE
    RAISE EXCEPTION 'trigger for gltrans table called in unexpected state.';
  END IF;
  RETURN NEW;
END;

Function: public._gltransinserttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _reqNotes BOOLEAN;
  _externalCompany      BOOLEAN := false;
BEGIN
  -- Checks
  -- Start with privileges
  IF ((NEW.gltrans_doctype='JE') AND (NOT checkPrivilege('PostJournalEntries'))) THEN
      RAISE EXCEPTION 'You do not have privileges to create a Journal Entry.';
  END IF;

  SELECT company_external INTO _externalCompany
  FROM company JOIN accnt ON (company_number=accnt_company)
  WHERE (accnt_id=NEW.gltrans_accnt_id);
  IF (_externalCompany) THEN
    RAISE EXCEPTION 'Transactions are not allowed for G/L Accounts with External Company segments.';
  END IF;
  -- RAISE NOTICE '_gltransInsertTrigger(): company_external = %', _externalCompany;

  SELECT metric_value='t'
    INTO _reqNotes
    FROM metric
   WHERE(metric_name='MandatoryGLEntryNotes');
  IF (_reqNotes IS NULL) THEN
    _reqNotes := false;
  END IF;
  IF ((NEW.gltrans_doctype='JE') AND _reqNotes AND (TRIM(BOTH FROM COALESCE(NEW.gltrans_notes,''))='')) THEN
      RAISE EXCEPTION 'Notes are required for Journal Entries.';
  END IF;
  
  RETURN NEW;
END;

Function: public._grpprivtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check BOOLEAN;
  _returnVal INTEGER;
BEGIN
  -- This looks like a candidate for a foreign key but isn't.
  -- fkeys don't work if the foreign key value resides in a child of the 
  -- table and not the table itself.
  IF ((TG_OP = 'UPDATE' OR TG_OP = 'INSERT') AND
      (NOT EXISTS(SELECT priv_id
                  FROM priv
                  WHERE (priv_id=NEW.grppriv_priv_id)))) THEN
    RAISE EXCEPTION 'Privilege id % does not exist or is part of a disabled package.',
                NEW.grppriv_priv_id;
    RETURN OLD;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._imageasstrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NEW.imageass_source = 'INCDT') THEN
    UPDATE incdt SET incdt_updated = now() WHERE incdt_id = NEW.imageass_source_id;
  END IF;

  RETURN NEW;
END;

Function: public._incdtbeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _recurid     INTEGER;
  _newparentid INTEGER;
BEGIN
  IF (TG_OP = 'DELETE') THEN
    SELECT recur_id INTO _recurid
      FROM recur
     WHERE ((recur_parent_id=OLD.incdt_id)
        AND (recur_parent_type='INCDT'));

     IF (_recurid IS NOT NULL) THEN
       SELECT MIN(incdt_id) INTO _newparentid
         FROM incdt
        WHERE ((incdt_recurring_incdt_id=OLD.inctd_id)
           AND (incdt_id!=OLD.incdt_id));

      -- client is responsible for warning about deleting a recurring incdt
      IF (_newparentid IS NULL) THEN
        DELETE FROM recur WHERE recur_id=_recurid;
      ELSE
        UPDATE recur SET recur_parent_id=_newparentid
         WHERE recur_id=_recurid;
      END IF;
    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._incdtbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _rec          RECORD;
  _check        BOOLEAN;
  _crmacct      INTEGER;

BEGIN

  IF(TG_OP = 'DELETE') THEN
    _rec := OLD;
  ELSE
    _rec := NEW;
  END IF;

  --  Checks
  IF (_rec.incdt_owner_username=getEffectiveXtUser()) THEN
    SELECT (checkPrivilege('MaintainAllIncidents') OR checkPrivilege('MaintainPersonalIncidents')) INTO _check;
  ELSE
    SELECT checkPrivilege('MaintainAllIncidents') INTO _check;
  END IF;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Incidents.';
  END IF;

  -- Set the incident number if blank
  IF (TG_OP = 'INSERT') THEN
    IF (NEW.incdt_number IS NULL) THEN
      SELECT fetchIncidentNumber() INTO NEW.incdt_number;
    END IF;

    --- clear the number from the issue cache
    PERFORM clearNumberIssue('IncidentNumber', NEW.incdt_number);
  END IF;

  -- Description is required
  IF (LENGTH(COALESCE(NEW.incdt_summary,''))=0) THEN
    RAISE EXCEPTION 'You must supply a valid Incident Description.';
  END IF;
  
  -- CRM Account is required
  IF (NEW.incdt_crmacct_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid CRM Account.';
  END IF;

  -- Contact is required
  IF (NEW.incdt_cntct_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Contact.';
  END IF;

  NEW.incdt_updated := now();

  RETURN NEW;
END;

Function: public._incdttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r		RECORD;
  _counter	INTEGER :=  0;
  _whsId	INTEGER := -1;
  _evntType	TEXT;
  _cmnttypeid   INTEGER := -1;
  _cmntid       INTEGER := -1;
BEGIN

  SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='Notes to Comment');
  IF NOT FOUND OR _cmnttypeid IS NULL THEN
    _cmnttypeid := -1;
  END IF;

  IF (TG_OP = 'DELETE') THEN
--  This should never happen
    RETURN OLD;
  ELSIF (TG_OP = 'INSERT') THEN
    INSERT INTO incdthist
	  (incdthist_incdt_id,
	   incdthist_change, incdthist_target_id,
	   incdthist_descrip)
    VALUES(NEW.incdt_id,
	   'N', NULL,
	   'Incident Added');

    _evntType = 'NewIncident';

    IF (_cmnttypeid <> -1 AND COALESCE(NEW.incdt_descrip, '') <> '') THEN
      PERFORM postComment(_cmnttypeid, 'INCDT', NEW.incdt_id, NEW.incdt_descrip);
    END IF;
  ELSIF (TG_OP = 'UPDATE') THEN
    _evntType = 'UpdatedIncident';

    IF (COALESCE(NEW.incdt_cntct_id,-1) <> COALESCE(OLD.incdt_cntct_id,-1)) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'C', NEW.incdt_cntct_id,
	     ('Contact Changed: "' ||
	       COALESCE((SELECT cntct_first_name || ' ' || cntct_last_name
			   FROM cntct
			  WHERE (cntct_id=OLD.incdt_cntct_id)), '')
	      || '" -> "' ||
	       COALESCE((SELECT cntct_first_name || ' ' || cntct_last_name
			   FROM cntct
			  WHERE (cntct_id=NEW.incdt_cntct_id)), '')
	      || '"') );
    END IF;

    IF (COALESCE(NEW.incdt_summary,'') <> COALESCE(OLD.incdt_summary,'')) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     ('Summary Updated: "' ||
	       COALESCE(OLD.incdt_summary, '') ||
	      '" -> "' ||
	       COALESCE(NEW.incdt_summary, '') ||
	      '"') );
    END IF;

    IF (COALESCE(NEW.incdt_descrip,'') <> COALESCE(OLD.incdt_descrip,'')) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     ('Description Updated: "' ||
	       substr(COALESCE(OLD.incdt_descrip, ''), 1, 20) ||
	      '..." -> "' ||
	       substr(COALESCE(NEW.incdt_descrip, ''), 1, 20) ||
	      '..."') );

      IF (_cmnttypeid <> -1) THEN
        -- find an existing comment
        SELECT comment_id
          INTO _cmntid
          FROM comment
         WHERE comment_source = 'INCDT'
           AND comment_source_id = NEW.incdt_id
           AND comment_cmnttype_id = _cmnttypeid;
        IF FOUND THEN
          UPDATE comment SET comment_text = NEW.incdt_descrip WHERE comment_id = _cmntid;
        ELSE
          PERFORM postComment(_cmnttypeid, 'INCDT', NEW.incdt_id, NEW.incdt_descrip);
        END IF;
      END IF;
    END IF;

    IF (NEW.incdt_status <> OLD.incdt_status) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'S', NULL,
	     ('Status Changed: ' ||
	      CASE WHEN(OLD.incdt_status='N') THEN 'New'
		   WHEN(OLD.incdt_status='F') THEN 'Feedback'
		   WHEN(OLD.incdt_status='C') THEN 'Confirmed'
		   WHEN(OLD.incdt_status='A') THEN 'Assigned'
		   WHEN(OLD.incdt_status='R') THEN 'Resolved'
		   WHEN(OLD.incdt_status='L') THEN 'Closed'
		   ELSE OLD.incdt_status
	      END
	      || ' -> ' ||
	      CASE WHEN(NEW.incdt_status='N') THEN 'New'
		   WHEN(NEW.incdt_status='F') THEN 'Feedback'
		   WHEN(NEW.incdt_status='C') THEN 'Confirmed'
		   WHEN(NEW.incdt_status='A') THEN 'Assigned'
		   WHEN(NEW.incdt_status='R') THEN 'Resolved'
		   WHEN(NEW.incdt_status='L') THEN 'Closed'
		   ELSE NEW.incdt_status
	      END
	      ) );
      IF (NEW.incdt_status = 'L') THEN
	_evntType = 'ClosedIncident';
      ELSIF (OLD.incdt_status = 'L') THEN
	_evntType = 'ReopenedIncident';
      END IF;
    END IF;

    IF (COALESCE(NEW.incdt_assigned_username,'') <> COALESCE(OLD.incdt_assigned_username,'')) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'A', NULL,
	     ('Assigned to: "' ||
	       COALESCE(OLD.incdt_assigned_username, '') ||
	      '" -> "' ||
	       COALESCE(NEW.incdt_assigned_username, '') ||
	      '"') );
    END IF;

    IF (COALESCE(NEW.incdt_incdtcat_id,-1) <> COALESCE(OLD.incdt_incdtcat_id,-1)) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'T', NEW.incdt_incdtcat_id,
	     ('Category Changed: ' ||
	       COALESCE((SELECT incdtcat_name
			   FROM incdtcat
			  WHERE (incdtcat_id=OLD.incdt_incdtcat_id)), '')
	      || ' -> ' ||
	       COALESCE((SELECT incdtcat_name
			   FROM incdtcat
			  WHERE (incdtcat_id=NEW.incdt_incdtcat_id)), '')
	      || '') );
    END IF;

    IF (COALESCE(NEW.incdt_incdtseverity_id,-1) <> COALESCE(OLD.incdt_incdtseverity_id,-1)) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'V', NEW.incdt_incdtseverity_id,
	     ('Severity Changed: ' ||
	       COALESCE((SELECT incdtseverity_name
			   FROM incdtseverity
			  WHERE (incdtseverity_id=OLD.incdt_incdtseverity_id)), '')
	      || ' -> ' ||
	       COALESCE((SELECT incdtseverity_name
			   FROM incdtseverity
			  WHERE (incdtseverity_id=NEW.incdt_incdtseverity_id)), '')
	      || '') );
    END IF;

    IF (COALESCE(NEW.incdt_incdtpriority_id,-1) <> COALESCE(OLD.incdt_incdtpriority_id,-1)) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'P', NEW.incdt_incdtpriority_id,
	     ('Priority Changed: ' ||
	       COALESCE((SELECT incdtpriority_name
			   FROM incdtpriority
			  WHERE (incdtpriority_id=OLD.incdt_incdtpriority_id)), '')
	      || ' -> ' ||
	       COALESCE((SELECT incdtpriority_name
			   FROM incdtpriority
			  WHERE (incdtpriority_id=NEW.incdt_incdtpriority_id)), '')
	      || '') );
    END IF;

    IF (COALESCE(NEW.incdt_incdtresolution_id,-1) <> COALESCE(OLD.incdt_incdtresolution_id,-1)) THEN
      INSERT INTO incdthist
	    (incdthist_incdt_id,
	     incdthist_change, incdthist_target_id,
	     incdthist_descrip)
      VALUES(NEW.incdt_id,
	     'E', NEW.incdt_incdtresolution_id,
	     ('Resolution Changed: ' ||
	       COALESCE((SELECT incdtresolution_name
			   FROM incdtresolution
			  WHERE (incdtresolution_id=OLD.incdt_incdtresolution_id)), '')
	      || ' -> ' ||
	       COALESCE((SELECT incdtresolution_name
			   FROM incdtresolution
			  WHERE (incdtresolution_id=NEW.incdt_incdtresolution_id)), '')
	      || '') );
    END IF;
  END IF;

  -- find the warehouse for which to create evntlog entries
    SELECT usrpref_value  INTO _whsId
    FROM usrpref
    WHERE usrpref_username = getEffectiveXtUser()
      AND usrpref_name = 'PreferredWarehouse';

  INSERT INTO evntlog (evntlog_evnttime, evntlog_username,
		       evntlog_evnttype_id, evntlog_ordtype,
		       evntlog_ord_id, evntlog_warehous_id, evntlog_number)
  SELECT DISTINCT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
		       'IC', NEW.incdt_id, _whsId, NEW.incdt_number
  FROM evntnot, evnttype
  WHERE ((evntnot_evnttype_id=evnttype_id)
    AND  (evnttype_name=_evntType));

  RETURN NEW;
  END;

Function: public._invcheadaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  DECLARE
    _cmnttypeid INTEGER;
    _cohead_id INTEGER;

  BEGIN
--  Create a comment entry when on a Sales Order when an Invoice is Posted for that order

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'UPDATE') THEN
	IF ((OLD.invchead_posted != NEW.invchead_posted) AND NEW.invchead_posted) THEN
	  SELECT cohead_id INTO _cohead_id
	  FROM cohead
	  WHERE (cohead_number = OLD.invchead_ordernumber);
	  IF (FOUND) THEN
            PERFORM postComment( _cmnttypeid, 'S', _cohead_id,
                                 ('Invoice, ' || NEW.invchead_invcnumber || ', posted for this order') );
          END IF;
	END IF;
      END IF;
    END IF;
  RETURN NEW;
  END;

Function: public._invcheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _recurid     INTEGER;
  _newparentid INTEGER;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.invchead_posted
      AND ((OLD.invchead_invcnumber != NEW.invchead_invcnumber)
        OR (OLD.invchead_invcdate != NEW.invchead_invcdate)
        OR (OLD.invchead_terms_id != NEW.invchead_terms_id)
        OR (OLD.invchead_salesrep_id != NEW.invchead_salesrep_id)
        OR (OLD.invchead_commission != NEW.invchead_commission)
        OR (OLD.invchead_taxzone_id != NEW.invchead_taxzone_id)
        OR (OLD.invchead_shipchrg_id != NEW.invchead_shipchrg_id)
        OR (OLD.invchead_prj_id != NEW.invchead_prj_id)
        OR (OLD.invchead_misc_accnt_id != NEW.invchead_misc_accnt_id)
        OR (OLD.invchead_misc_amount != NEW.invchead_misc_amount)
        OR (OLD.invchead_freight != NEW.invchead_freight))) THEN
      RAISE EXCEPTION 'Edit not allow on Posted Invoice.';
    END IF;
  END IF;
  
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM invcheadtax
    WHERE (taxhist_parent_id=OLD.invchead_id);

    SELECT recur_id INTO _recurid
      FROM recur
     WHERE ((recur_parent_id=OLD.invchead_id)
        AND (recur_parent_type='I'));
    IF (_recurid IS NOT NULL) THEN
      SELECT invchead_id INTO _newparentid
        FROM invchead
       WHERE ((invchead_recurring_invchead_id=OLD.invchead_id)
          AND (invchead_id!=OLD.invchead_id))
       ORDER BY invchead_invcdate
       LIMIT 1;

      IF (_newparentid IS NULL) THEN
        DELETE FROM recur WHERE recur_id=_recurid;
      ELSE
        UPDATE recur SET recur_parent_id=_newparentid
         WHERE recur_id=_recurid;
        UPDATE invchead SET invchead_recurring_invchead_id=_newparentid
         WHERE invchead_recurring_invchead_id=OLD.invchead_id
           AND invchead_id!=OLD.invchead_id;
      END IF;
    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._invcheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    -- Something can go here
    RETURN OLD;
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Freight Tax
    IF (NEW.invchead_freight <> 0) THEN
      PERFORM calculateTaxHist( 'invcheadtax',
                                NEW.invchead_id,
                                NEW.invchead_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.invchead_invcdate,
                                NEW.invchead_curr_id,
                                NEW.invchead_freight );
    END IF;

    --- clear the number from the issue cache
    PERFORM clearNumberIssue('InvcNumber', NEW.invchead_invcnumber);
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

    IF ( (NEW.invchead_freight <> OLD.invchead_freight) OR
         (COALESCE(NEW.invchead_taxzone_id,-1) <> COALESCE(OLD.invchead_taxzone_id,-1)) OR
         (NEW.invchead_invcdate <> OLD.invchead_invcdate) OR
         (NEW.invchead_curr_id <> OLD.invchead_curr_id) ) THEN
  -- Calculate invchead Tax
      PERFORM calculateTaxHist( 'invcheadtax',
                                NEW.invchead_id,
                                NEW.invchead_taxzone_id,
                                getFreightTaxtypeId(),
                                NEW.invchead_invcdate,
                                NEW.invchead_curr_id,
                                NEW.invchead_freight );
    END IF;

    IF ( (COALESCE(NEW.invchead_taxzone_id,-1) <> COALESCE(OLD.invchead_taxzone_id,-1)) OR
         (NEW.invchead_invcdate <> OLD.invchead_invcdate) OR
         (NEW.invchead_curr_id <> OLD.invchead_curr_id) ) THEN
  -- Calculate invcitem Tax
      IF (COALESCE(NEW.invchead_taxzone_id,-1) <> COALESCE(OLD.invchead_taxzone_id,-1)) THEN

        UPDATE invcitem SET invcitem_taxtype_id=getItemTaxType(invcitem_item_id,NEW.invchead_taxzone_id)
        WHERE (invcitem_invchead_id=NEW.invchead_id);

        PERFORM calculateTaxHist( 'invcitemtax',
                                  invcitem_id,
                                  NEW.invchead_taxzone_id,
                                  invcitem_taxtype_id,
                                  NEW.invchead_invcdate,
                                  NEW.invchead_curr_id,
                                  (invcitem_billed * invcitem_qty_invuomratio) *
                                  (invcitem_price / invcitem_price_invuomratio) )
        FROM invcitem
        WHERE (invcitem_invchead_id = NEW.invchead_id);
      END IF;
    END IF;

  END IF;

  RETURN NEW;
END;

Function: public._invcitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _itemfractional BOOLEAN;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM invcitemtax
    WHERE (taxhist_parent_id=OLD.invcitem_id);

    RETURN OLD;
  END IF;

  IF (TG_OP IN ('UPDATE','DELETE')) THEN
    IF (SELECT COUNT(invchead_id) > 0
        FROM invchead
        WHERE ((invchead_id=OLD.invcitem_invchead_id)
          AND (invchead_posted))) THEN
      RAISE EXCEPTION 'Edit not allowed on Posted Invoices.';
    END IF;
  END IF;

  -- If regular Item then enforce item_fractional
  IF (COALESCE(NEW.invcitem_item_id, -1) <> -1) THEN
    SELECT itemuomfractionalbyuom(NEW.invcitem_item_id, NEW.invcitem_qty_uom_id) INTO _itemfractional;
    IF (NOT _itemfractional) THEN
      IF (TRUNC(NEW.invcitem_ordered) <> NEW.invcitem_ordered) THEN
        RAISE EXCEPTION 'Item does not support fractional quantities';
      END IF;
      IF (TRUNC(NEW.invcitem_billed) <> NEW.invcitem_billed) THEN
        RAISE EXCEPTION 'Item does not support fractional quantities';
      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._invcitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

-- Cache Invoice Head
  SELECT * INTO _r
  FROM invchead
  WHERE (invchead_id=NEW.invcitem_invchead_id);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Invoice head not found';
  END IF;

-- Insert new row
  IF (TG_OP = 'INSERT') THEN

  -- Calculate Tax
      PERFORM calculateTaxHist( 'invcitemtax',
                                NEW.invcitem_id,
                                COALESCE(_r.invchead_taxzone_id, -1),
                                NEW.invcitem_taxtype_id,
                                COALESCE(_r.invchead_invcdate, CURRENT_DATE),
                                COALESCE(_r.invchead_curr_id, -1),
                                (NEW.invcitem_billed * NEW.invcitem_qty_invuomratio) *
                                (NEW.invcitem_price / NEW.invcitem_price_invuomratio) );
  END IF;

-- Update row
  IF (TG_OP = 'UPDATE') THEN

  -- Calculate Tax
    IF ( (NEW.invcitem_billed <> OLD.invcitem_billed) OR
         (NEW.invcitem_qty_invuomratio <> OLD.invcitem_qty_invuomratio) OR
         (NEW.invcitem_price <> OLD.invcitem_price) OR
         (NEW.invcitem_price_invuomratio <> OLD.invcitem_price_invuomratio) OR
         (COALESCE(NEW.invcitem_taxtype_id, -1) <> COALESCE(OLD.invcitem_taxtype_id, -1)) ) THEN
      PERFORM calculateTaxHist( 'invcitemtax',
                                NEW.invcitem_id,
                                COALESCE(_r.invchead_taxzone_id, -1),
                                NEW.invcitem_taxtype_id,
                                COALESCE(_r.invchead_invcdate, CURRENT_DATE),
                                COALESCE(_r.invchead_curr_id, -1),
                                (NEW.invcitem_billed * NEW.invcitem_qty_invuomratio) *
                                (NEW.invcitem_price / NEW.invcitem_price_invuomratio) );
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._ipsassbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  --  Checks
  IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
  END IF;

  -- Business logic, disallow invalid combinations
  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    IF (LENGTH(COALESCE(NEW.ipsass_custtype_pattern,'')) != 0) THEN
      new.ipsass_cust_id 		= 	-1;
      new.ipsass_custtype_id 		= 	-1;
      new.ipsass_shipto_id		= 	-1;
      new.ipsass_shipto_pattern	=	'';
    ELSIF (COALESCE(NEW.ipsass_custtype_id,-1) > -1) THEN
      new.ipsass_cust_id 		= 	-1;
      new.ipsass_shipto_id		= 	-1;
      new.ipsass_shipto_pattern	=	'';
      new.ipsass_custtype_pattern	=	'';
    ELSIF (LENGTH(COALESCE(NEW.ipsass_shipto_pattern,'')) != 0) THEN
      new.ipsass_custtype_id 		= 	-1;
      new.ipsass_shipto_id		= 	-1;
      new.ipsass_custtype_pattern	=	'';
    ELSE
      new.ipsass_shipto_id		= 	COALESCE(NEW.ipsass_shipto_id,-1);
      new.ipsass_custtype_id 		= 	-1;
      new.ipsass_shipto_pattern	=	'';
      new.ipsass_custtype_pattern	=	'';
    END IF;

    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
  
END;

Function: public._ipsheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  --  Checks
  IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
  END IF;

  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
END;

Function: public._ipsitemcharbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  --  Checks
  IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
  END IF;
  
  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    IF (SELECT (COUNT(item_id)=0)
        FROM ipsiteminfo JOIN item ON (item_id=ipsitem_item_id) 
        WHERE ((ipsitem_id=NEW.ipsitemchar_ipsitem_id)
        AND (item_config))) THEN
      RAISE EXCEPTION 'Characteristic prices may only be set on configured items.';
    ELSIF (SELECT (COUNT(item_id)=0)
        FROM ipsiteminfo JOIN item ON (item_id=ipsitem_item_id)
                         JOIN charass ON (charass_target_id=item_id AND charass_target_type='I') 
        WHERE ((ipsitem_id=NEW.ipsitemchar_ipsitem_id)
        AND (charass_char_id=NEW.ipsitemchar_char_id)
        AND (charass_value=NEW.ipsitemchar_value))) THEN
      RAISE EXCEPTION 'No characteristic with matching value exists for this item.';
    END IF;
    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
END;

Function: public._ipsiteminfobeforetrigger()

Returns: trigger

Language: PLPGSQL

BEGIN

  --  Checks
  IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
  END IF;
  
  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    RETURN NEW;
  ELSE
    RETURN OLD;
  END IF;
END;

Function: public._itemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN
-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Items.';
   END IF;
   
-- Integrity checks
  IF (TG_OP = 'UPDATE') THEN
    IF ((OLD.item_type <> NEW.item_type) AND (NEW.item_type = 'L')) THEN
      IF (SELECT COUNT(*) != 0 FROM bomitem WHERE (bomitem_item_id = OLD.item_id)) THEN
        RAISE EXCEPTION 'This item is part of one or more Bills of Materials and cannot be a Planning Item.';
      END IF;
    END IF;

    IF ((OLD.item_type <> NEW.item_type) AND
       (NEW.item_type IN ('R','S','T'))) THEN
      IF (SELECT COUNT(*) != 0
        FROM itemsite
        WHERE ((itemsite_item_id=OLD.item_id)
        AND (itemsite_qtyonhand + qtyallocated(itemsite_id,startoftime(),endoftime()) +
	   qtyordered(itemsite_id,startoftime(),endoftime()) > 0 ))) THEN
          RAISE EXCEPTION 'Item type not allowed when there are itemsites with quantities with on hand quantities or pending inventory activity for this item.';
      END IF;
    END IF;
-- If type changed remove costs and deactivate item sites
    IF (NEW.item_type <> OLD.item_type) THEN
      PERFORM updateCost(itemcost_id, 0) FROM itemcost WHERE (itemcost_item_id=OLD.item_id);
      UPDATE itemsite SET itemsite_active=false WHERE (itemsite_item_id=OLD.item_id);
      IF (NEW.item_type = 'R') THEN
        UPDATE itemsite SET itemsite_controlmethod='N' WHERE (itemsite_item_id=OLD.item_id);
      END IF;
    END IF;
  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='ItemChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'I', NEW.item_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.item_active <> NEW.item_active) THEN
          IF (NEW.item_active) THEN
            PERFORM postComment(_cmnttypeid, 'I', NEW.item_id, 'Activated');
          ELSE
            PERFORM postComment(_cmnttypeid, 'I', NEW.item_id, 'Deactivated');
          END IF;
        END IF;

        IF (OLD.item_descrip1 <> NEW.item_descrip1) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Description 1 Changed from "' || OLD.item_descrip1 ||
                                 '" to "' || NEW.item_descrip1 || '"' ) );
        END IF;

        IF (OLD.item_descrip2 <> NEW.item_descrip2) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Description 2 Changed from "' || OLD.item_descrip2 ||
                                 '" to "' || NEW.item_descrip2 || '"' ) );
        END IF;

        IF (OLD.item_inv_uom_id <> NEW.item_inv_uom_id) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Inventory UOM Changed from "' ||
                                 (SELECT uom_name FROM uom WHERE uom_id=OLD.item_inv_uom_id) ||
                                 '" (' || CAST(OLD.item_inv_uom_id AS TEXT) ||
                                 ') to "' ||
                                 (SELECT uom_name FROM uom WHERE uom_id=NEW.item_inv_uom_id) ||
                                 '" (' || CAST(NEW.item_inv_uom_id AS TEXT) || ')' ) );
        END IF;

        IF (OLD.item_sold <> NEW.item_sold) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               CASE WHEN (NEW.item_sold) THEN 'Sold Changed from FALSE to TRUE'
                                    ELSE 'Sold Changed from TRUE to FALSE'
                               END );
        END IF;

        IF (OLD.item_picklist <> NEW.item_picklist) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               CASE WHEN (NEW.item_picklist) THEN 'Pick List Changed from FALSE to TRUE'
                                    ELSE 'Pick List Changed from TRUE to FALSE'
                               END );
        END IF;

        IF (OLD.item_fractional <> NEW.item_fractional) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               CASE WHEN (NEW.item_fractional) THEN 'Fractional Changed from FALSE to TRUE'
                                    ELSE 'Fractional Changed from TRUE to FALSE'
                               END );
        END IF;

        IF (OLD.item_exclusive <> NEW.item_exclusive) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               CASE WHEN (NEW.item_exclusive) THEN 'Exclusive Changed from FALSE to TRUE'
                                    ELSE 'Exclusive Changed from TRUE to FALSE'
                               END );
        END IF;
        IF (OLD.item_config <> NEW.item_config) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               CASE WHEN (NEW.item_config) THEN 'Configured Changed from FALSE to TRUE'
                                    ELSE 'Configured Changed from TRUE to FALSE'
                               END );
        END IF;

        IF (OLD.item_listprice <> NEW.item_listprice) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'List Price Changed from "' || formatSalesPrice(OLD.item_listprice) ||
                                 '" to "' || formatSalesPrice(NEW.item_listprice) || '"' ) );
        END IF;

-- Add New stuff

        IF (OLD.item_type <> NEW.item_type) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Type Changed from "' || OLD.item_type ||
                                 '" to "' || NEW.item_type || '"' ) );
        END IF;

        IF (OLD.item_price_uom_id <> NEW.item_price_uom_id) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Price UOM Changed from "' ||
                                 (SELECT uom_name FROM uom WHERE uom_id=OLD.item_price_uom_id) ||
                                 '" (' || CAST(OLD.item_price_uom_id AS TEXT) ||
                                 ') to "' ||
                                 (SELECT uom_name FROM uom WHERE uom_id=NEW.item_price_uom_id) ||
                                 '" (' || CAST(NEW.item_price_uom_id AS TEXT) || ')' ) );
        END IF;

        IF (OLD.item_classcode_id <> NEW.item_classcode_id) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Class Code Changed from "' ||
                                 (SELECT classcode_code || '-' || classcode_descrip FROM classcode WHERE classcode_id=OLD.item_classcode_id) ||
                                 '" (' || CAST(OLD.item_classcode_id AS TEXT) ||
                                 ') to "' ||
                                 (SELECT classcode_code || '-' || classcode_descrip FROM classcode WHERE classcode_id=NEW.item_classcode_id) ||
                                 '" (' || CAST(NEW.item_classcode_id AS TEXT) || ')' ) );
        END IF;

        IF (OLD.item_freightclass_id <> NEW.item_freightclass_id) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Freight Class Changed from "' ||
                                 (SELECT freightclass_code || '-' || freightclass_descrip FROM freightclass WHERE freightclass_id=OLD.item_freightclass_id) ||
                                 '" (' || CAST(OLD.item_freightclass_id AS TEXT) ||
                                 ') to "' ||
                                 (SELECT freightclass_code || '-' || freightclass_descrip FROM freightclass WHERE freightclass_id=NEW.item_freightclass_id) ||
                                 '" (' || CAST(NEW.item_freightclass_id AS TEXT) || ')' ) );
        END IF;

        IF (OLD.item_prodcat_id <> NEW.item_prodcat_id) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Product Category Changed from "' ||
                                 (SELECT prodcat_code || '-' || prodcat_descrip FROM prodcat WHERE prodcat_id=OLD.item_prodcat_id) ||
                                 '" (' || CAST(OLD.item_prodcat_id AS TEXT) ||
                                 ') to "' ||
                                 (SELECT prodcat_code || '-' || prodcat_descrip FROM prodcat WHERE prodcat_id=NEW.item_prodcat_id) ||
                                 '" (' || CAST(NEW.item_prodcat_id AS TEXT) || ')' ) );
        END IF;

        IF (OLD.item_upccode <> NEW.item_upccode) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'UPC Code Changed from "' || OLD.item_upccode ||
                                 '" to "' || NEW.item_upccode || '"' ) );
        END IF;

        IF (OLD.item_prodweight <> NEW.item_prodweight) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Product Weight Changed from "' || formatWeight(OLD.item_prodweight) ||
                                 '" to "' || formatWeight(NEW.item_prodweight) || '"' ) );
        END IF;

        IF (OLD.item_packweight <> NEW.item_packweight) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Packaging Weight Changed from "' || formatWeight(OLD.item_packweight) ||
                                 '" to "' || formatWeight(NEW.item_packweight) || '"' ) );
        END IF;

        IF (OLD.item_maxcost <> NEW.item_maxcost) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'Maximum Desired Cost Changed from "' || formatCost(OLD.item_maxcost) ||
                                 '" to "' || formatCost(NEW.item_maxcost) || '"' ) );
        END IF;

        IF (OLD.item_listcost <> NEW.item_listcost) THEN
          PERFORM postComment( _cmnttypeid, 'I', NEW.item_id,
                               ( 'List Cost Changed from "' || formatCost(OLD.item_listcost) ||
                                 '" to "' || formatCost(NEW.item_listcost) || '"' ) );
        END IF;
-- End changes

      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    DELETE FROM imageass WHERE ((imageass_source_id=OLD.item_id) AND (imageass_source='I'));
    DELETE FROM url WHERE ((url_source_id=OLD.item_id) AND (url_source='I'));

    RETURN OLD;
  END IF;
  
  RETURN NEW;

END;

Function: public._itemaliastrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Item Aliases.';
   END IF;
  
  RETURN NEW;
END;

Function: public._itemcostaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _itemNumber TEXT;
  _maxCost NUMERIC;
  _oldStdCost NUMERIC;
  _oldActCost NUMERIC;
  _costElem TEXT;
BEGIN

--  Create Event if Standard or Actual Cost is greater than Max Cost

  SELECT item_number, item_maxcost INTO _itemNumber, _maxCost
  FROM item
  WHERE (item_id=NEW.itemcost_item_id);

  SELECT costelem_type INTO _costElem
  FROM costelem
  WHERE (costelem_id=NEW.itemcost_costelem_id);

  IF (_maxCost > 0.0) THEN
    IF (stdCost(NEW.itemcost_item_id) > _maxCost) 
      AND
      ( 
               (SELECT COUNT(evntlog_id) FROM
                      evntlog, evnttype
                      WHERE evntlog_evnttype_id = evnttype_id 
                      AND evntlog_number LIKE 
                           (_itemNumber || '%' || 
                           'New: ' || formatCost(stdCost(NEW.itemcost_item_id)) || 
                           ' Max: ' || formatCost(_maxCost))
                      AND CAST(evntlog_evnttime AS DATE) = current_date
                      ) = 0)
       THEN
      IF (TG_OP = 'INSERT') THEN
        _oldStdCost := 0;
        _oldActCost := 0;
      ELSE
        _oldStdCost := OLD.itemcost_stdcost;
        _oldActCost := OLD.itemcost_stdcost;
      END IF; 
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                            evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                            evntlog_newvalue, evntlog_oldvalue )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
             '', NEW.itemcost_item_id, itemsite_warehous_id,
               (_itemNumber || ' -Standard- ' || 
               'New: ' || formatCost(stdCost(NEW.itemcost_item_id)) ||
               ' Max: '|| formatCost(_MaxCost)),
               NEW.itemcost_stdcost, _oldStdCost
      FROM evntnot, evnttype, itemsite
      WHERE ( (evntnot_evnttype_id=evnttype_id)
        AND   (itemsite_item_id=NEW.itemcost_item_id)
        AND   (evntnot_warehous_id=itemsite_warehous_id)
        AND   (evnttype_name='CostExceedsMaxDesired') );
    END IF;
    IF (actCost(NEW.itemcost_item_id) > _maxCost) 
     AND   ( 
                (SELECT COUNT(evntlog_id) FROM
                      evntlog, evnttype
                      WHERE evntlog_evnttype_id = evnttype_id 
                      AND evntlog_number LIKE 
                           (_itemNumber || '%' || 
                           'New: ' || formatCost(actCost(NEW.itemcost_item_id)) || 
                           ' Max: ' || formatCost(_maxCost))
                      AND CAST(evntlog_evnttime AS DATE) = current_date
                      ) = 0
              )
      THEN
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                            evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                            evntlog_newvalue, evntlog_oldvalue )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
             '', NEW.itemcost_item_id, itemsite_warehous_id,
               (_itemNumber || ' -Actual- ' || 
               'New: ' || formatCost(actCost(NEW.itemcost_item_id)) ||
               ' Max: '|| formatCost(_MaxCost)),
             NEW.itemcost_actcost, _oldActCost
      FROM evntnot, evnttype, itemsite
      WHERE ( (evntnot_evnttype_id=evnttype_id)
        AND   (itemsite_item_id=NEW.itemcost_item_id)
        AND   (evntnot_warehous_id=itemsite_warehous_id)
        AND   (evnttype_name='CostExceedsMaxDesired') );
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._itemcosttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  --Privilege Checks
  IF ( (TG_OP = 'INSERT') AND (NOT checkPrivilege('CreateCosts')) AND (NOT checkPrivilege('PostVouchers')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to enter Item Costs.';
  END IF;

  IF ( (TG_OP = 'UPDATE') AND (NOT checkPrivilege('EnterActualCosts')) AND (NOT checkPrivilege('PostVouchers')) AND (NOT checkPrivilege('UpdateActualCosts')) AND (NOT checkPrivilege('PostActualCosts')) AND (NOT checkPrivilege('PostStandardCosts')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to update Item Costs.';
  END IF;

  IF ( (TG_OP = 'DELETE') AND (NOT checkPrivilege('DeleteCosts')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to delete Item Costs.';
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    IF (NEW.itemcost_actcost <> OLD.itemcost_actcost OR
        NEW.itemcost_curr_id <> OLD.itemcost_curr_id) THEN
      INSERT INTO costhist
      ( costhist_item_id, costhist_costelem_id, costhist_type,
        costhist_lowlevel, costhist_username, costhist_date,
        costhist_oldcost, costhist_newcost,
        costhist_oldcurr_id, costhist_newcurr_id )
      VALUES
      ( NEW.itemcost_item_id, NEW.itemcost_costelem_id, 'A',
        NEW.itemcost_lowlevel, getEffectiveXtUser(), CURRENT_TIMESTAMP,
        OLD.itemcost_actcost, NEW.itemcost_actcost,
        OLD.itemcost_curr_id, NEW.itemcost_curr_id );
    END IF;

    IF (NEW.itemcost_stdcost <> OLD.itemcost_stdcost) THEN
      INSERT INTO costhist
      ( costhist_item_id, costhist_costelem_id, costhist_type,
        costhist_lowlevel, costhist_username, costhist_date,
        costhist_oldcost, costhist_newcost,
        costhist_oldcurr_id, costhist_newcurr_id )
      VALUES
      ( NEW.itemcost_item_id, NEW.itemcost_costelem_id, 'S',
        NEW.itemcost_lowlevel, getEffectiveXtUser(), CURRENT_TIMESTAMP,
        OLD.itemcost_stdcost, NEW.itemcost_stdcost,
        baseCurrId(), baseCurrId() );
    END IF;

    RETURN NEW;

  ELSIF (TG_OP = 'INSERT') THEN
    INSERT INTO costhist
    ( costhist_item_id, costhist_costelem_id, costhist_type,
      costhist_lowlevel, costhist_username, costhist_date,
      costhist_oldcost, costhist_newcost,
      costhist_oldcurr_id, costhist_newcurr_id )
    VALUES
    ( NEW.itemcost_item_id, NEW.itemcost_costelem_id, 'N',
      NEW.itemcost_lowlevel, getEffectiveXtUser(), CURRENT_TIMESTAMP,
      0, NEW.itemcost_actcost,
      baseCurrId(), NEW.itemcost_curr_id );

    RETURN NEW;

  ELSIF (TG_OP = 'DELETE') THEN
    INSERT INTO costhist
    ( costhist_item_id, costhist_costelem_id, costhist_type,
      costhist_lowlevel, costhist_username, costhist_date,
      costhist_oldcost, costhist_newcost,
      costhist_oldcurr_id, costhist_newcurr_id )
    VALUES
    ( OLD.itemcost_item_id, OLD.itemcost_costelem_id, 'D',
      OLD.itemcost_lowlevel, getEffectiveXtUser(), CURRENT_TIMESTAMP,
      OLD.itemcost_stdcost, 0,
      OLD.itemcost_curr_id, baseCurrId() );

    RETURN OLD;
  END IF;

END;

Function: public._itemsiteaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _state INTEGER;
  _wasLocationControl BOOLEAN;
  _isLocationControl BOOLEAN;
  _wasLotSerial BOOLEAN;
  _isLotSerial BOOLEAN;
  _wasPerishable BOOLEAN;
  _isPerishable BOOLEAN;
  _qty NUMERIC;
  _maint BOOLEAN;
  _cost NUMERIC;
  _variance NUMERIC;
  _application TEXT;

BEGIN
-- Cache Application
  SELECT fetchMetricText('Application') INTO _application;

-- Check if we are doing maintenance
  IF (TG_OP = 'INSERT') THEN
    _maint := TRUE;
  ELSIF (TG_OP = 'UPDATE') THEN
    IF ((OLD.itemsite_item_id           != NEW.itemsite_item_id)
     OR (OLD.itemsite_warehous_id       != NEW.itemsite_warehous_id)
     OR (OLD.itemsite_reorderlevel      != NEW.itemsite_reorderlevel)
     OR (OLD.itemsite_ordertoqty        != NEW.itemsite_ordertoqty)
     OR (OLD.itemsite_cyclecountfreq    != NEW.itemsite_cyclecountfreq)
     OR (OLD.itemsite_planning_type     != NEW.itemsite_planning_type)
     OR (OLD.itemsite_posupply          != NEW.itemsite_posupply)
     OR (OLD.itemsite_wosupply          != NEW.itemsite_wosupply)
     OR (OLD.itemsite_loccntrl          != NEW.itemsite_loccntrl)
     OR (OLD.itemsite_safetystock       != NEW.itemsite_safetystock)
     OR (OLD.itemsite_minordqty         != NEW.itemsite_minordqty)
     OR (OLD.itemsite_multordqty        != NEW.itemsite_multordqty)
     OR (OLD.itemsite_leadtime          != NEW.itemsite_leadtime)
     OR (OLD.itemsite_abcclass          != NEW.itemsite_abcclass)
     OR (OLD.itemsite_controlmethod     != NEW.itemsite_controlmethod)
     OR (OLD.itemsite_active            != NEW.itemsite_active)
     OR (OLD.itemsite_plancode_id       != NEW.itemsite_plancode_id)
     OR (OLD.itemsite_costcat_id        != NEW.itemsite_costcat_id)
     OR (OLD.itemsite_eventfence        != NEW.itemsite_eventfence)
     OR (OLD.itemsite_sold              != NEW.itemsite_sold)
     OR (OLD.itemsite_stocked           != NEW.itemsite_stocked)
     OR (OLD.itemsite_location_id       != NEW.itemsite_location_id)
     OR (OLD.itemsite_useparams         != NEW.itemsite_useparams)
     OR (OLD.itemsite_useparamsmanual   != NEW.itemsite_useparamsmanual)
     OR (OLD.itemsite_soldranking       != NEW.itemsite_soldranking)
     OR (OLD.itemsite_createpr          != NEW.itemsite_createpr)
     OR (OLD.itemsite_location          != NEW.itemsite_location)
     OR (OLD.itemsite_location_comments != NEW.itemsite_location_comments)
     OR (OLD.itemsite_notes             != NEW.itemsite_notes)
     OR (OLD.itemsite_perishable        != NEW.itemsite_perishable)
     OR (OLD.itemsite_autoabcclass      != NEW.itemsite_autoabcclass)
     OR (OLD.itemsite_ordergroup        != NEW.itemsite_ordergroup)
     OR (OLD.itemsite_disallowblankwip  != NEW.itemsite_disallowblankwip)
     OR (OLD.itemsite_maxordqty         != NEW.itemsite_maxordqty)
     OR (OLD.itemsite_mps_timefence     != NEW.itemsite_mps_timefence)
     OR (OLD.itemsite_createwo          != NEW.itemsite_createwo)
     OR (OLD.itemsite_warrpurc          != NEW.itemsite_warrpurc)
     OR (OLD.itemsite_costmethod        != NEW.itemsite_costmethod)
     OR (OLD.itemsite_autoreg           != NEW.itemsite_autoreg)
     OR (OLD.itemsite_lsseq_id          != NEW.itemsite_lsseq_id) ) THEN
      IF (OLD.itemsite_item_id != NEW.itemsite_item_id) THEN
        RAISE EXCEPTION 'The item number on an itemsite may not be changed.';
      ELSIF (OLD.itemsite_warehous_id != NEW.itemsite_warehous_id) THEN
        RAISE EXCEPTION 'The warehouse code on an itemsite may not be changed.';
      END IF;
      _maint := TRUE;
    END IF;
  ELSE
    _maint := FALSE;
  END IF;

  IF (_maint) THEN -- Begin Maintenance
-- Privilege Checks
    IF ( NOT checkPrivilege('MaintainItemSites') ) THEN
       RAISE EXCEPTION 'You do not have privileges to maintain Item Sites.';
    END IF;
    
-- Override values to avoid invalid data combinations
    IF (NOT NEW.itemsite_posupply) THEN
      UPDATE itemsite SET
        itemsite_createpr = FALSE
      WHERE (itemsite_id=NEW.itemsite_id);
    END IF;
    IF (NOT NEW.itemsite_wosupply) THEN
      UPDATE itemsite SET
        itemsite_createwo = FALSE
      WHERE (itemsite_id=NEW.itemsite_id);
    END IF;

    IF (NEW.itemsite_controlmethod NOT IN ('S','L')) THEN
      UPDATE itemsite SET
        itemsite_perishable = FALSE,
        itemsite_warrpurc = FALSE,
        itemsite_autoreg = FALSE,
        itemsite_lsseq_id = NULL
      WHERE (itemsite_id=NEW.itemsite_id);
    END IF;

    IF (NOT NEW.itemsite_loccntrl) THEN
      UPDATE itemsite SET
        itemsite_disallowblankwip = FALSE
      WHERE (itemsite_id=NEW.itemsite_id);
    END IF;

    IF (NOT NEW.itemsite_useparams) THEN
      UPDATE itemsite SET
        itemsite_reorderlevel    = 0,
        itemsite_ordertoqty      = 0,
        itemsite_minordqty       = 0,
        itemsite_maxordqty       = 0,
        itemsite_multordqty      = 0,
        itemsite_useparamsmanual = FALSE
      WHERE (itemsite_id = NEW.itemsite_id);
    END IF;
    
-- Integrity check
    IF (TG_OP = 'INSERT') THEN
      -- Handle MLC logic
      IF ( (NEW.itemsite_loccntrl) AND (NEW.itemsite_warehous_id IS NOT NULL) ) THEN
        IF (SELECT count(*)=0
            FROM location
            WHERE ((location_warehous_id=NEW.itemsite_warehous_id)
            AND ( (NOT location_restrict) OR
                ( (location_restrict) AND
                (location_id IN ( SELECT locitem_location_id
                                  FROM locitem
                                  WHERE (locitem_item_id=NEW.itemsite_item_id) ) ) ) ))) THEN
          RAISE EXCEPTION 'You must first create at least one valid
	    		  Location for this Item Site before it may be
	   	          multiply located.';
        END IF;
      END IF;

      --This could be made a table constraint later, but do not want to create a big problem
      --for users with problematic legacy data over a relatively trivial problem for now,
      --so we will just check moving forword.
      IF (NEW.itemsite_stocked AND NEW.itemsite_reorderlevel<=0) THEN
        RAISE EXCEPTION 'Stocked items must have postive reorder level specified.';
      END IF;
    END IF;

    IF (TG_OP = 'UPDATE') THEN
      --This could be made a table constraint later, but do not want to create a big problem
      --for users with problematic legacy data over a relatively trivial problem for now,
      --so we will just check moving forword.
      IF ((NEW.itemsite_stocked)
        AND (NEW.itemsite_stocked != OLD.itemsite_stocked) --Avoid checking unless explicitly changed
        AND (NEW.itemsite_reorderlevel<=0)) THEN
        RAISE EXCEPTION 'Stocked items must have postive reorder level specified.';
      END IF;
    END IF;
  
    IF (TG_OP = 'UPDATE') THEN
  
-- Integrity check
      IF (NOT OLD.itemsite_loccntrl AND NEW.itemsite_loccntrl) THEN
        IF (SELECT count(*)=0
          FROM location
          WHERE ((location_warehous_id=NEW.itemsite_warehous_id)
          AND ( (NOT location_restrict) OR
              ( (location_restrict) AND
              (location_id IN ( SELECT locitem_location_id
                                FROM locitem
                                WHERE (locitem_item_id=NEW.itemsite_item_id) ) ) ) ))) THEN
           RAISE EXCEPTION 'You must first create at least one valid
			  Location for this Item Site before it may be
		          multiply located.';
        END IF;
      END IF;
   
-- Update detail records based on control method changes 
      _wasLocationControl := OLD.itemsite_loccntrl;
      _isLocationControl := NEW.itemsite_loccntrl;
      _wasLotSerial := OLD.itemsite_controlmethod IN ('S','L');
      _isLotSerial := NEW.itemsite_controlmethod IN ('S','L'); 
      _wasPerishable := OLD.itemsite_perishable;
      _isPerishable := NEW.itemsite_perishable;
      _state := 0;
    
      IF ( (_wasLocationControl) AND (_isLocationControl) ) THEN
        _state := 10;
      ELSIF ( (NOT _wasLocationControl) AND (NOT _isLocationControl) ) THEN
        _state := 20;
      ELSIF ( (NOT _wasLocationControl) AND (_isLocationControl) ) THEN
        _state := 30;
      ELSIF ( (_wasLocationControl) AND (NOT _isLocationControl) ) THEN
        _state := 40;
      END IF;

      IF ( (_wasLotSerial) AND (_isLotSerial) ) THEN
        _state := _state + 1;
      ELSIF ( (NOT _wasLotSerial) AND (NOT _isLotSerial) ) THEN
        _state := _state + 2;
      ELSIF ( (NOT _wasLotSerial) AND (_isLotSerial) ) THEN
        _state := _state + 3;
      ELSIF ( (_wasLotSerial) AND (NOT _isLotSerial) ) THEN
        _state := _state + 4;
      END IF;

      IF ( (_application = 'Standard') AND (_state IN (41, 43, 14, 34, 24, 42, 44)) ) THEN
        -- Check for Reservations
        IF (SELECT COUNT(*) > 0
            FROM itemloc JOIN itemlocrsrv ON (itemlocrsrv_itemloc_id=itemloc_id)
            WHERE (itemloc_itemsite_id=OLD.itemsite_id)) THEN
          RAISE EXCEPTION 'Sales Order Reservations by Location exist for this Item Site';
        END IF;
      END IF;

      IF (_state IN (41, 43)) THEN
        PERFORM consolidateLotSerial(OLD.itemsite_id);
      ELSIF (_state IN (14, 34)) THEN
        PERFORM consolidateLocations(OLD.itemsite_id);
      ELSIF (_state IN (24, 42, 44)) THEN

        RAISE NOTICE 'Deleting item site detail records,';

        SELECT SUM(itemloc_qty) INTO _qty
        FROM itemloc, location
        WHERE ((itemloc_location_id=location_id)
        AND (NOT location_netable) 
        AND (itemloc_itemsite_id=OLD.itemsite_id));

        IF (_qty != 0) THEN
          UPDATE itemsite
          SET itemsite_qtyonhand = itemsite_qtyonhand + _qty,
            itemsite_nnqoh = itemsite_nnqoh - _qty
          WHERE (itemsite_id=OLD.itemsite_id);
        END IF;

        DELETE FROM itemloc
        WHERE (itemloc_itemsite_id=OLD.itemsite_id);
      END IF;

     IF (NEW.itemsite_qtyonhand != 0) THEN
--  Handle detail creation
--  Create itemloc records if they do not exist
       IF (_state IN (23, 32, 33)) THEN
          INSERT INTO itemloc 
            ( itemloc_itemsite_id, itemloc_location_id,
              itemloc_expiration, itemloc_qty )
            VALUES
            ( NEW.itemsite_id, -1,
              endOfTime(), NEW.itemsite_qtyonhand );
        END IF;

--  Handle Location distribution
        IF (_state IN (31, 32, 33, 34)) THEN
          IF (SELECT (COUNT(*)=1)
              FROM location
              WHERE ((location_id=NEW.itemsite_location_id)
              AND (location_warehous_id=NEW.itemsite_warehous_id)
              AND ( (NOT location_restrict) OR
                  ( (location_restrict) AND
                  (location_id IN ( SELECT locitem_location_id
                                    FROM locitem
                                    WHERE (locitem_item_id=NEW.itemsite_item_id) ) ) ) ))) THEN
           PERFORM initialDistribution(NEW.itemsite_id, NEW.itemsite_location_id);
          ELSE
            RAISE EXCEPTION 'A valid default location must be selected to distribute existing inventory to.';
          END IF;
        END IF;

--  Handle Lot/Serial distribution
        IF ( (_state = 13) OR (_state = 23) OR (_state = 33) OR (_state = 43) ) THEN
          RAISE NOTICE 'You should now use the Reassign Lot/Serial # window to assign Lot/Serial #s.';
        END IF;
      END IF;  
      IF (OLD.itemsite_costmethod='A' AND NEW.itemsite_costmethod='S') THEN
        -- TODO: Average costing cost method change
        SELECT stdcost(NEW.itemsite_item_id) * NEW.itemsite_qtyonhand
          INTO _cost;
        _variance := _cost - NEW.itemsite_value;
        NEW.itemsite_value := _cost;
        IF(_variance <> 0.0) THEN
          PERFORM insertGLTransaction( 'P/D', '', '', 'Itemsite converted from Average to Standard cost.',
                                       costcat_invcost_accnt_id, costcat_asset_accnt_id, NEW.itemsite_id,
                                      _variance, CURRENT_DATE )
             FROM costcat
            WHERE(costcat_id=NEW.itemsite_costcat_id);
          UPDATE itemsite SET itemsite_value = _cost WHERE (itemsite_id = NEW.itemsite_id);
        END IF;
      END IF;
    END IF;

--  Handle Perishable
    IF ( (_application = 'Standard') AND (_wasPerishable) AND (NOT _isPerishable) ) THEN
      UPDATE itemloc SET itemloc_expiration = endOfTime()
      WHERE (itemloc_itemsite_id = OLD.itemsite_id);
      PERFORM consolidateLotSerial(OLD.itemsite_id);
    END IF;

--  If Planning Type changed to None then delete all Planned Orders
    IF ( (_application = 'Standard') AND (TG_OP = 'UPDATE') ) THEN
      IF (NEW.itemsite_planning_type = 'N' AND OLD.itemsite_planning_type <> 'N') THEN
        PERFORM deletePlannedOrder(planord_id, TRUE)
        FROM planord
        WHERE (planord_itemsite_id=NEW.itemsite_id);
      END IF;
    END IF;
    
  END IF;  -- End Maintenance

  RETURN NEW;

END;

Function: public._itemsitetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _r RECORD;

BEGIN

  -- Cache some information
  SELECT item_type INTO _r
  FROM item
  WHERE (item_id=NEW.itemsite_item_id);
 
-- Override values to avoid invalid data combinations
  IF (_r.item_type IN ('J','R','S')) THEN
    NEW.itemsite_planning_type := 'N';
  END IF;

  IF (_r.item_type = 'L') THEN
    NEW.itemsite_planning_type := 'S';
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    IF ( (NEW.itemsite_qtyonhand <> OLD.itemsite_qtyonhand) ) THEN
      IF (OLD.itemsite_freeze) THEN
        NEW.itemsite_qtyonhand := OLD.itemsite_qtyonhand;
      ELSE
        NEW.itemsite_datelastused := CURRENT_DATE;
      END IF;

      IF ( (NEW.itemsite_qtyonhand < 0) AND (OLD.itemsite_qtyonhand >= 0) AND (NEW.itemsite_eventfence > 0) ) THEN
        INSERT INTO evntlog
        ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
          evntlog_number )
        SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
               'I', NEW.itemsite_id, warehous_id,
               (item_number || '/' || warehous_code)
        FROM evntnot, evnttype, item, whsinfo
        WHERE ( (evntnot_evnttype_id=evnttype_id)
         AND (evntnot_warehous_id=NEW.itemsite_warehous_id)
         AND (NEW.itemsite_item_id=item_id)
         AND (NEW.itemsite_warehous_id=warehous_id)
         AND (evnttype_name='QOHBelowZero') );
      END IF;
    END IF;
    IF ( (NEW.itemsite_value <> OLD.itemsite_value) AND (OLD.itemsite_freeze) ) THEN
      NEW.itemsite_value := OLD.itemsite_value;
    END IF;
  END IF;

  IF (NEW.itemsite_qtyonhand < 0 AND NEW.itemsite_costmethod = 'A') THEN
    RAISE EXCEPTION 'Itemsite (%) is set to use average costing and is not allowed to have a negative quantity on hand.', NEW.itemsite_id;
  ELSIF (NEW.itemsite_value < 0 AND NEW.itemsite_costmethod = 'A') THEN
    RAISE EXCEPTION 'This transaction results in a negative itemsite value.  Itemsite (%) is set to use average costing and is not allowed to have a negative value.', NEW.itemsite_id;
  END IF;

--  Handle the ChangeLog
  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='ItemSiteChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'IS', NEW.itemsite_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN

        IF (OLD.itemsite_plancode_id <> NEW.itemsite_plancode_id) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Planner Code Changed from "' || oldplancode.plancode_code ||
                                 '" to "' || newplancode.plancode_code || '"' ) )
          FROM plancode AS oldplancode, plancode AS newplancode
          WHERE ( (oldplancode.plancode_id=OLD.itemsite_plancode_id)
           AND (newplancode.plancode_id=NEW.itemsite_plancode_id) );
        END IF;

        IF (NEW.itemsite_reorderlevel <> OLD.itemsite_reorderlevel) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Reorder Level Changed from ' || formatQty(OLD.itemsite_reorderlevel) ||
                                 ' to ' || formatQty(NEW.itemsite_reorderlevel ) ) );
        END IF;

        IF (NEW.itemsite_ordertoqty <> OLD.itemsite_ordertoqty) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Order Up To Changed from ' || formatQty(OLD.itemsite_ordertoqty) ||
                                 ' to ' || formatQty(NEW.itemsite_ordertoqty ) ) );
        END IF;

        IF (NEW.itemsite_leadtime <> OLD.itemsite_leadtime) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Itemsite Leadtime Changed from ' || formatQty(OLD.itemsite_leadtime) ||
                                 ' to ' || formatQty(NEW.itemsite_leadtime ) ) );
        END IF;

        IF (NEW.itemsite_abcclass <> OLD.itemsite_abcclass) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Itemsite ABC Class Changed from ' || COALESCE(OLD.itemsite_abcclass, 'None') ||
                                 ' to ' || COALESCE(NEW.itemsite_abcclass,'None') ) );
        END IF;

        IF (NEW.itemsite_controlmethod <> OLD.itemsite_controlmethod) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
                               ( 'Itemsite Control Method Changed from ' || COALESCE(OLD.itemsite_controlmethod,'None') ||
                                 ' to ' || COALESCE(NEW.itemsite_controlmethod,'None') ) );
        END IF;

        IF (OLD.itemsite_sold <> NEW.itemsite_sold) THEN
          PERFORM postComment( _cmnttypeid, 'IS', NEW.itemsite_id,
            CASE WHEN (NEW.itemsite_sold) THEN 'Sold Changed from FALSE to TRUE'
                                          ELSE 'Sold Changed from TRUE to FALSE'
            END );
        END IF;

        IF (OLD.itemsite_active <> NEW.itemsite_active) THEN
          IF (NEW.itemsite_active) THEN
            PERFORM postComment(_cmnttypeid, 'IS', NEW.itemsite_id, 'Activated');
          ELSE
            PERFORM postComment(_cmnttypeid, 'IS', NEW.itemsite_id, 'Deactivated');
          END IF;
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._itemsrcaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
  IF (NOT checkPrivilege('MaintainItemSources')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Item Sources.';
  END IF;

-- Set default to false for other item sources of this item
  IF (COALESCE(NEW.itemsrc_default, FALSE) = TRUE) THEN
    UPDATE itemsrc SET itemsrc_default = FALSE
    WHERE ( (itemsrc_item_id = NEW.itemsrc_item_id)
      AND (itemsrc_id <> NEW.itemsrc_id) );
  END IF;

  RETURN NEW;
END;

Function: public._itemsrcptrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemSources')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Item Sources.';
   END IF;

-- Set defaults
   NEW.itemsrcp_curr_id	:= COALESCE(NEW.itemsrcp_curr_id,basecurrid());
  
  RETURN NEW;
END;

Function: public._itemsrctrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemSources')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Item Sources.';
   END IF;

-- Set defaults
   NEW.itemsrc_invvendoruomratio	:= COALESCE(NEW.itemsrc_invvendoruomratio,1);
   NEW.itemsrc_minordqty		:= COALESCE(NEW.itemsrc_minordqty,0);
   NEW.itemsrc_multordqty		:= COALESCE(NEW.itemsrc_multordqty,0);
   NEW.itemsrc_active			:= COALESCE(NEW.itemsrc_active,true);
   NEW.itemsrc_leadtime			:= COALESCE(NEW.itemsrc_leadtime,0);
   NEW.itemsrc_ranking			:= COALESCE(NEW.itemsrc_ranking,1);
  
  RETURN NEW;
END;

Function: public._itemsubtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Item Substitutes.';
   END IF;
  
  RETURN NEW;
END;

Function: public._itemtaxtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Items.';
   END IF;
  
  RETURN NEW;
END;

Function: public._itemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
 
-- Override values to avoid invalid data combinations
  IF (NEW.item_type IN ('R','S','O','L','B')) THEN
    NEW.item_picklist := FALSE;
  END IF;

  IF (NEW.item_type IN ('F','S','O','L','B')) THEN
    NEW.item_picklist := FALSE;
    NEW.item_sold := FALSE;
    NEW.item_prodcat_id := -1;
    NEW.item_exclusive := false;
    NEW.item_listprice := 0;
    NEW.item_upccode := '';
    NEW.item_prodweight := 0;
    NEW.item_packweight := 0;
  END IF;

  IF (NEW.item_type NOT IN ('M','R')) THEN
    NEW.item_config := false;
  END IF;

  RETURN NEW;

END;

Function: public._itemuomconvtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

-- Privilege Checks
   IF (NOT checkPrivilege('MaintainItemMasters')) THEN
     RAISE EXCEPTION 'You do not have privileges to maintain Items.';
   END IF;
  
  RETURN NEW;
END;

Function: public._locationaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _itemloc    RECORD;

BEGIN

  -- Maintain itemsite_qtyonhand and itemsite_nnqoh when location_netable changes
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.location_netable <> NEW.location_netable) THEN
      FOR _itemloc IN SELECT * FROM itemloc WHERE (itemloc_location_id=NEW.location_id) LOOP
        IF (NEW.location_netable) THEN
          UPDATE itemsite SET itemsite_qtyonhand = itemsite_qtyonhand + _itemloc.itemloc_qty,
                              itemsite_nnqoh = itemsite_nnqoh - _itemloc.itemloc_qty
          WHERE (itemsite_id=_itemloc.itemloc_itemsite_id);
        ELSE
          UPDATE itemsite SET itemsite_qtyonhand = itemsite_qtyonhand - _itemloc.itemloc_qty,
                              itemsite_nnqoh = itemsite_nnqoh + _itemloc.itemloc_qty
          WHERE (itemsite_id=_itemloc.itemloc_itemsite_id);
        END IF;
      END LOOP;
    END IF;
  END IF;
  
  RETURN NEW;

END;

Function: public._locationtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _checkId    INTEGER;

BEGIN

  -- Checks
  -- Start with privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainLocations') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add new Locations.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainLocations') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Location.';
    END IF;
  END IF;

  -- Code is required
  IF ( (LENGTH(COALESCE(NEW.location_name,''))=0) AND
       (LENGTH(COALESCE(NEW.location_aisle,''))=0) AND
       (LENGTH(COALESCE(NEW.location_rack,''))=0) AND
       (LENGTH(COALESCE(NEW.location_bin,''))=0) ) THEN
    RAISE EXCEPTION 'You must supply a valid Location Identifier.';
  END IF;
  
  -- Site is required
  IF (NEW.location_warehous_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Site.';
  END IF;

  -- Location Identifier must be unique
  SELECT location_id INTO _checkId
  FROM location
  WHERE ( (UPPER(location_name)=UPPER(NEW.location_name))
    AND   (UPPER(location_aisle)=UPPER(NEW.location_aisle))
    AND   (UPPER(location_rack)=UPPER(NEW.location_rack))
    AND   (UPPER(location_bin)=UPPER(NEW.location_bin))
    AND   (location_warehous_id=NEW.location_warehous_id)
    AND   (location_id<>NEW.location_id) );
  IF (FOUND) THEN
    RAISE EXCEPTION 'You must supply a unique Location Identifier for this Site.';
  END IF;
  
  RETURN NEW;

END;

Function: public._metasqlaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT (isDBA() OR checkPrivilege('MaintainMetaSQL'))) THEN
    RAISE EXCEPTION '% does not have privileges to maintain MetaSQL statements in %.%',
                getEffectiveXtUser(), TG_TABLE_SCHEMA, TG_TABLE_NAME;
  END IF;

  IF ((TG_OP = 'UPDATE' OR TG_OP = 'DELETE')
      AND NEW.metasql_grade <= 0
      AND NOT isDBA()) THEN
    RAISE EXCEPTION 'You may not alter grade 0 metasql queries except using the xTuple Updater utility';
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;


Function: public._metasqltrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  NEW.metasql_lastuser 		:= getEffectiveXtUser();
  NEW.metasql_lastupdate 	:= current_date;
  RETURN NEW;

END;


Function: public._opheadaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
BEGIN

  --  Comments
  IF ( SELECT (metric_value='t') FROM metric WHERE (metric_name='OpportunityChangeLog') ) THEN

    --  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'OPP', NEW.ophead_id, 'Created');

        --- clear the number from the issue cache
        PERFORM clearNumberIssue('OpportunityNumber', NEW.ophead_number);
      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.ophead_active <> NEW.ophead_active) THEN
          IF (NEW.ophead_active) THEN
            PERFORM postComment(_cmnttypeid, 'OPP', NEW.ophead_id, 'Activated');
          ELSE
            PERFORM postComment(_cmnttypeid, 'OPP', NEW.ophead_id, 'Deactivated');
          END IF;
        END IF;

        IF (OLD.ophead_name <> NEW.ophead_name) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Name Changed from "' || OLD.ophead_name ||
                                 '" to "' || NEW.ophead_name || '"' ) );
        END IF;

        IF (OLD.ophead_owner_username <> NEW.ophead_owner_username) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Owner Name Changed from "' || OLD.ophead_owner_username ||
                                 '" to "' || NEW.ophead_owner_username || '"' ) );
        END IF;

        IF (OLD.ophead_probability_prcnt <> NEW.ophead_probability_prcnt) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Probability % Changed from "' || OLD.ophead_probability_prcnt ||
                                 '" to "' || NEW.ophead_probability_prcnt || '"' ) );
        END IF;

        IF (OLD.ophead_amount <> NEW.ophead_amount) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Amount Changed from "' || OLD.ophead_amount ||
                                 '" to "' || NEW.ophead_amount || '"' ) );
        END IF;

        IF (OLD.ophead_target_date <> NEW.ophead_target_date) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Target Date Changed from "' || OLD.ophead_target_date ||
                                 '" to "' || NEW.ophead_target_date || '"' ) );
        END IF;

        IF (OLD.ophead_actual_date <> NEW.ophead_actual_date) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Actual Date Changed from "' || OLD.ophead_actual_date ||
                                 '" to "' || NEW.ophead_actual_date || '"' ) );
        END IF;

        IF (OLD.ophead_crmacct_id <> NEW.ophead_crmacct_id) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'CRM Account Changed from "' ||
                                 (SELECT crmacct_name FROM crmacct WHERE crmacct_id=OLD.ophead_crmacct_id) ||
                                 '" (' || OLD.ophead_crmacct_id ||
                                 ') to "' ||
                                 (SELECT crmacct_name FROM crmacct WHERE crmacct_id=NEW.ophead_crmacct_id) ||
                                 '" (' || NEW.ophead_crmacct_id || ')' ) );
        END IF;

        IF (OLD.ophead_curr_id <> NEW.ophead_curr_id) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Currency Changed from "' ||
                                 (SELECT curr_name FROM curr_symbol WHERE curr_id=OLD.ophead_curr_id) ||
                                 '" (' || OLD.ophead_curr_id ||
                                 ') to "' ||
                                 (SELECT curr_name FROM curr_symbol WHERE curr_id=NEW.ophead_curr_id) ||
                                 '" (' || NEW.ophead_curr_id || ')' ) );
        END IF;

        IF (OLD.ophead_opstage_id <> NEW.ophead_opstage_id) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Stage Changed from "' ||
                                 (SELECT opstage_name FROM opstage WHERE opstage_id=OLD.ophead_opstage_id) ||
                                 '" (' || OLD.ophead_opstage_id ||
                                 ') to "' ||
                                 (SELECT opstage_name FROM opstage WHERE opstage_id=NEW.ophead_opstage_id) ||
                                 '" (' || NEW.ophead_opstage_id || ')' ) );
        END IF;

        IF (OLD.ophead_opsource_id <> NEW.ophead_opsource_id) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Source Changed from "' ||
                                 (SELECT opsource_name FROM opsource WHERE opsource_id=OLD.ophead_opsource_id) ||
                                 '" (' || OLD.ophead_opsource_id ||
                                 ') to "' ||
                                 (SELECT opsource_name FROM opsource WHERE opsource_id=NEW.ophead_opsource_id) ||
                                 '" (' || NEW.ophead_opsource_id || ')' ) );
        END IF;

        IF (OLD.ophead_optype_id <> NEW.ophead_optype_id) THEN
          PERFORM postComment( _cmnttypeid, 'OPP', NEW.ophead_id,
                               ( 'Type Changed from "' ||
                                 (SELECT optype_name FROM optype WHERE optype_id=OLD.ophead_optype_id) ||
                                 '" (' || OLD.ophead_optype_id ||
                                 ') to "' ||
                                 (SELECT optype_name FROM optype WHERE optype_id=NEW.ophead_optype_id) ||
                                 '" (' || NEW.ophead_optype_id || ')' ) );
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._opheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _rec record;
  _check boolean;
  _test text;
BEGIN

  IF(TG_OP = 'DELETE') THEN
    _rec := OLD;
  ELSE
    _rec := NEW;
  END IF;

  --  Auto inactivate
  IF (TG_OP = 'UPDATE') THEN
    IF ( (NEW.ophead_opstage_id != OLD.ophead_opstage_id) AND
         (SELECT opstage_opinactive FROM opstage WHERE opstage_id=NEW.ophead_opstage_id) ) THEN
      NEW.ophead_active := FALSE;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._packbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
BEGIN
  SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
  IF (FOUND) THEN
    IF ((TG_OP = 'INSERT') AND (NEW.pack_head_id) IS NOT NULL)THEN
      PERFORM postComment(_cmnttypeid, 'S', NEW.pack_head_id, 'Added to Packing List Batch');
    END IF;
  END IF;
  IF ((TG_OP = 'INSERT') OR (TG_OP = 'UPDATE')) THEN
    IF (NEW.pack_shiphead_id IS NOT NULL
	 AND NEW.pack_shiphead_id NOT IN (SELECT shiphead_id
			       FROM shiphead
			       WHERE (shiphead_order_id=NEW.pack_head_id)
				 AND (shiphead_order_type=NEW.pack_head_type))) THEN
      RAISE EXCEPTION 'Shipment does not exist for % id %',
		      NEW.pack_head_type, NEW.pack_head_id;
      RETURN OLD;
    END IF;

    IF (NEW.pack_head_type = 'SO'
	AND NEW.pack_head_id   IN (SELECT cohead_id FROM cohead)) THEN
      RETURN NEW;

    ELSEIF (NEW.pack_head_type = 'TO') THEN
      IF (NOT fetchMetricBool('MultiWhs')) THEN
	RAISE EXCEPTION 'Transfer Orders are not supported by this version of the application';
      ELSEIF (NEW.pack_head_id IN (SELECT tohead_id FROM tohead)) THEN
	RETURN NEW;
      END IF;
    END IF;

    RAISE EXCEPTION '% with id % does not exist',
		    NEW.pack_head_type, NEW.pack_head_id;
    RETURN OLD;

  END IF;

  RETURN NEW;
END;

Function: public._periodaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _idoffirst INTEGER;
  _test      INTEGER;
BEGIN
  -- This trigger can easily cause an infinite loop
  -- because of this we have to be very careful to not
  -- do an update on the period table if no updates
  -- are absolutely needed so we don't just keep
  -- trigger ourselves again and again

  -- Figure out which period is the first one
  SELECT period_id
    INTO _idoffirst
    FROM period
   ORDER BY period_start
   LIMIT 1;

  -- If we didn't find anything there is nothing to do
  IF( NOT FOUND ) THEN
    RETURN NEW;
  END IF;

  -- do a select to see if there is at least one record that needs to be
  -- updated. If we do not find any then we can just leave without
  -- causing a retrigger of ourselves
  SELECT period_id
    INTO _test
    FROM period
   WHERE((COALESCE(period_initial, true) AND (NOT period_id=_idoffirst))
      OR ((NOT COALESCE(period_initial, false)) AND (period_id=_idoffirst)))
   LIMIT 1;

  -- Nothing to update - get out of here
  IF( NOT FOUND ) THEN
    RETURN NEW;
  END IF;

  -- Update all the period records that already have the initial flag
  -- set and the one that we know should be the first.
  -- We don't have to be as careful here since we have already ruled
  -- out if don't need to update already.
  UPDATE period
     SET period_initial = (_idoffirst=period_id)
   WHERE((COALESCE(period_initial, true))
      OR (period_id=_idoffirst));

  RETURN NEW;

END;

Function: public._pkgcmdaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgcmdaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create custom commands in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter custom commands in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete custom commands from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;


Function: public._pkgcmdargaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;
  RETURN NEW;
END;

Function: public._pkgcmdargaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create command arguments in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter command arguments in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete command arguments from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;


Function: public._pkgcmdargbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmdargid     INTEGER;
  _debug        BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'INSERT') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgcmdbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmdid       INTEGER;
  _debug        BOOL := false;

BEGIN
    IF (TG_OP = 'UPDATE') THEN
      IF (_debug) THEN
        RAISE NOTICE 'OLD.cmd_name %, NEW.cmd_name %',
                     OLD.cmd_name, NEW.cmd_name;
      END IF;

      IF (NEW.cmd_name != OLD.cmd_name) THEN
        SELECT cmd_id INTO _cmdid FROM cmd WHERE cmd_name=NEW.cmd_name;
        IF (FOUND) THEN
          RAISE EXCEPTION 'Cannot change command name % because another command with that name already exists.', NEW.cmd_name;
        END IF;
      END IF;

    ELSIF (TG_OP = 'INSERT') THEN
      IF (_debug) THEN
        RAISE NOTICE 'inserting NEW.cmd_name %', NEW.cmd_name;
      END IF;
      SELECT cmd_id INTO _cmdid FROM cmd WHERE cmd_name=NEW.cmd_name;
      IF (FOUND) THEN
        RAISE EXCEPTION 'Cannot create new command % because another command with that name already exists.', NEW.cmd_name;
      END IF;

    ELSIF (TG_OP = 'DELETE') THEN
      DELETE FROM cmdarg WHERE cmdarg_cmd_id=OLD.cmd_id;

      RETURN OLD;
    END IF;

    RETURN NEW;
  END;

Function: public._pkgheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  DECLARE
    _r    RECORD;

  BEGIN
    IF (TG_OP = 'UPDATE') THEN
      NEW.pkghead_created := OLD.pkghead_created;
      NEW.pkghead_updated := CURRENT_TIMESTAMP;
      IF (NEW.pkghead_indev AND NOT userCanCreateUsers(getEffectiveXtUser())) THEN
        NEW.pkghead_indev = FALSE;
      END IF;

    ELSIF (TG_OP = 'INSERT') THEN
      NEW.pkghead_created := CURRENT_TIMESTAMP;
      NEW.pkghead_updated := NEW.pkghead_created;
      IF (NEW.pkghead_indev AND NOT userCanCreateUsers(getEffectiveXtUser())) THEN
        NEW.pkghead_indev = FALSE;
      END IF;

    ELSIF (TG_OP = 'DELETE') THEN
      DELETE FROM pkgdep WHERE pkgdep_pkghead_id=OLD.pkghead_id;

      EXECUTE 'DROP SCHEMA ' || OLD.pkghead_name || ' CASCADE';

      RETURN OLD;
    END IF;

    RETURN NEW;
  END;

Function: public._pkgimageaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgimagealtertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create images in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter images in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete images from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;

Function: public._pkgimagebeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _imageid     INTEGER;
  _debug       BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    IF (_debug) THEN
      RAISE NOTICE 'OLD.image_name %, NEW.image_name %',
                   OLD.image_name, NEW.image_name;
    END IF;

    IF (NEW.image_name != OLD.image_name) THEN
      SELECT image_id INTO _imageid FROM image WHERE image_name=NEW.image_name;
      IF (FOUND) THEN
        RAISE EXCEPTION 'Cannot change image named % because another image with that name already exists.', NEW.image_name;
      END IF;
    END IF;

  ELSIF (TG_OP = 'INSERT') THEN
    IF (_debug) THEN
      RAISE NOTICE 'inserting NEW.image_name %', NEW.image_name;
    END IF;
    SELECT image_id INTO _imageid FROM image WHERE image_name=NEW.image_name;
    IF (FOUND) THEN
      RAISE EXCEPTION 'Cannot create new image % because another image with that name already exists.', NEW.image_name;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;

  END IF;

  RETURN NEW;
END;

Function: public._pkgitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  DECLARE
    _functionargs TEXT;
    _group        TEXT;
    _object       TEXT;
    _schema       TEXT;
    _debug        BOOL := false;
  BEGIN
    IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
      _object = NEW.pkgitem_name;

      SELECT LOWER(pkghead_name) INTO _schema
      FROM pkghead
      WHERE (pkghead_id=NEW.pkgitem_pkghead_id);
      IF (NOT FOUND) THEN
        _schema := 'public';
      END IF;

      IF (NEW.pkgitem_type = 'F') THEN
        _object := SPLIT_PART(_object, '(', 1);
      ELSIF (NEW.pkgitem_type = 'M') THEN
        _group  := SPLIT_PART(_object, '-', 1);
        _object := SPLIT_PART(_object, '-', 2);
      END IF;
      IF _debug THEN
        RAISE NOTICE '_schema % and _object %', _schema, _object;
      END IF;

      IF (NEW.pkgitem_type = 'C') THEN
        IF (NOT EXISTS(SELECT script_id
                       FROM script
                       WHERE ((script_id=NEW.pkgitem_item_id)
                          AND (script_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Script % as a Package Item without a corresponding script record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'D') THEN
        IF (NOT EXISTS(SELECT cmd_id
                       FROM cmd
                       WHERE ((cmd_id=NEW.pkgitem_item_id)
                          AND (cmd_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Custom Command % as a Package Item without a corresponding cmd record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'F') THEN
        IF (NOT EXISTS(SELECT pg_proc.oid
                       FROM pg_proc, pg_namespace
                       WHERE ((pg_proc.oid=NEW.pkgitem_item_id)
                          AND (proname = (_object))
                          AND (pronamespace=pg_namespace.oid)
                          AND (nspname=_schema)) )) THEN
          RAISE EXCEPTION 'Cannot create Function % (oid %) as a Package Item without a corresponding function in the database.',
                          NEW.pkgitem_name, NEW.pkgitem_item_id;
        END IF;

      ELSIF (NEW.pkgitem_type = 'G') THEN
        IF (NOT EXISTS(SELECT pg_class.oid
                     FROM pg_trigger, pg_class, pg_namespace
                     WHERE ((tgname=_object)
                        AND (tgrelid=pg_class.oid)
                        AND (relnamespace=pg_namespace.oid)
                        AND (nspname=_schema)))) THEN
          RAISE EXCEPTION 'Cannot create Trigger % as a Package Item without a corresponding trigger in the database.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'I') THEN
        IF (NOT EXISTS(SELECT image_id
                       FROM image
                       WHERE ((image_id=NEW.pkgitem_item_id)
                          AND (image_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Image % as a Package Item without a corresponding image record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'M') THEN
        IF (NOT EXISTS(SELECT metasql_id
                       FROM metasql
                       WHERE ((metasql_id=NEW.pkgitem_item_id)
                          AND (metasql_group=_group)
                          AND (metasql_name=_object)))) THEN
          RAISE EXCEPTION 'Cannot create MetaSQL statement % as a Package Item without a corresponding metasql record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'P') THEN
        IF (NOT EXISTS(SELECT priv_id
                       FROM priv
                       WHERE ((priv_id=NEW.pkgitem_item_id)
                          AND (priv_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Privilege % as a Package Item without a corresponding priv record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'R') THEN
        IF (NOT EXISTS(SELECT report_id
                       FROM report
                       WHERE ((report_id=NEW.pkgitem_item_id)
                          AND (report_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Report % as a Package Item without a corresponding report record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'S') THEN
        IF (NOT EXISTS(SELECT oid
                       FROM pg_namespace
                       WHERE (LOWER(nspname)=LOWER(NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create Schema % as a Package Item without a corresponding schema in the database.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'T') THEN
        IF (NOT EXISTS(SELECT pg_class.oid
                     FROM pg_class, pg_namespace
                     WHERE ((relname=_object)
                        AND (relnamespace=pg_namespace.oid)
                        AND (relkind='r')
                        AND (nspname=_schema)))) THEN
          RAISE EXCEPTION 'Cannot create Table % as a Package Item without a corresponding table in the database.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'U') THEN
        IF (NOT EXISTS(SELECT uiform_id
                       FROM uiform
                       WHERE ((uiform_id=NEW.pkgitem_item_id)
                          AND (uiform_name=NEW.pkgitem_name)))) THEN
          RAISE EXCEPTION 'Cannot create User Interface Form % as a Package Item without a corresponding uiform record.',
            NEW.pkgitem_name;
        END IF;

      ELSIF (NEW.pkgitem_type = 'V') THEN
        IF (NOT EXISTS(SELECT pg_class.oid
                     FROM pg_class, pg_namespace
                     WHERE ((relname=_object)
                        AND (relnamespace=pg_namespace.oid)
                        AND (relkind='v')
                        AND (nspname=_schema)))) THEN
          RAISE EXCEPTION 'Cannot create View % as a Package Item without a corresponding view in the database.',
            NEW.pkgitem_name;
        END IF;

      ELSE
        RAISE EXCEPTION '"%" is not a valid type of package item.',
          NEW.pkgitem_type;
      END IF;

    ELSIF (TG_OP = 'DELETE') THEN
      IF _debug THEN RAISE NOTICE 'Deleting % % %', OLD.pkgitem_item_id, OLD.pkgitem_name, OLD.pkgitem_type; END IF;

      _object = OLD.pkgitem_name;

      SELECT pkghead_name INTO _schema
      FROM pkghead
      WHERE (pkghead_id=OLD.pkgitem_pkghead_id);
      IF (NOT FOUND) THEN
        _schema := 'public';
      END IF;

      IF (OLD.pkgitem_type = 'F') THEN
        _object := SPLIT_PART(_object, '(', 1);
      ELSIF (OLD.pkgitem_type = 'M') THEN
        _group  := SPLIT_PART(_object, '-', 1);
        _object := SPLIT_PART(_object, '-', 2);
      END IF;
      IF _debug THEN
        RAISE NOTICE '_schema % and _object %', _schema, _object;
      END IF;

      IF (OLD.pkgitem_type = 'C') THEN
        DELETE FROM script WHERE ((script_id=OLD.pkgitem_item_id)
                              AND (script_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'D') THEN
        DELETE FROM cmd
          WHERE ((cmd_id=OLD.pkgitem_item_id)
            AND  (cmd_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'F') THEN
        -- SELECT dropIfExists('FUNCTION', CAST (oid::regprocedure AS TEXT), _schema)
        PERFORM dropIfExists('FUNCTION',
                            proname || '(' ||
                            oidvectortypes(proargtypes) || ')',
                            _schema)
        FROM pg_proc
        WHERE (oid=OLD.pkgitem_item_id);

      ELSIF (OLD.pkgitem_type = 'G') THEN
        PERFORM dropIfExists('TRIGGER', _object, _schema);

      ELSIF (OLD.pkgitem_type = 'I') THEN
        DELETE FROM image WHERE ((image_id=OLD.pkgitem_item_id)
                             AND (image_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'M') THEN
        DELETE FROM metasql WHERE ((metasql_id=OLD.pkgitem_item_id)
                               AND (metasql_group=_group)
                               AND (metasql_name=_object));

      ELSIF (OLD.pkgitem_type = 'P') THEN
        DELETE FROM priv
        WHERE ((priv_id=OLD.pkgitem_item_id) 
           AND (priv_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'R') THEN
        DELETE FROM report
        WHERE ((report_id=OLD.pkgitem_item_id)
           AND (report_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'S') THEN
        PERFORM dropIfExists('SCHEMA', OLD.pkgitem_name, OLD.pkgitem_name);

      ELSIF (OLD.pkgitem_type = 'T') THEN
        PERFORM dropIfExists('TABLE', _object, _schema, true);

      ELSIF (OLD.pkgitem_type = 'U') THEN
        DELETE FROM uiform
        WHERE ((uiform_id=OLD.pkgitem_item_id)
           AND (uiform_name=OLD.pkgitem_name));

      ELSIF (OLD.pkgitem_type = 'V') THEN
        PERFORM dropIfExists('VIEW', _object, _schema, true);

      ELSE
        RAISE EXCEPTION '"%" is not a valid type of package item.',
          OLD.pkgitem_type;
      END IF;
      RETURN OLD;
    END IF;

    RETURN NEW;
  END;

Function: public._pkgmetasqlaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgmetasqlaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _isdba        BOOLEAN := false;

BEGIN
  SELECT rolsuper INTO _isdba FROM pg_roles WHERE (rolname=getEffectiveXtUser());

  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  -- cannot combine IF's because plpgsql does not always evaluate left-to-right
  IF (TG_OP = 'INSERT') THEN
    IF (NEW.metasql_grade <= 0 AND NOT _isdba) THEN
      RAISE EXCEPTION 'You may not create grade 0 MetaSQL statements in packages except using the xTuple Updater utility';
    END IF;

  ELSIF (TG_OP = 'UPDATE') THEN
    IF (NEW.metasql_grade <= 0 AND NOT _isdba) THEN
      RAISE EXCEPTION 'You may not alter grade 0 MetaSQL statements in packages except using the xTuple Updater utility';
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    IF (OLD.metasql_grade <= 0 AND NOT _isdba) THEN
      RAISE EXCEPTION 'You may not delete grade 0 MetaSQL statements from packages. Try deleting or disabling the package.';
    ELSE
      RETURN OLD;
    END IF;

  END IF;

  RETURN NEW;
END;

Function: public._pkgmetasqlbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _metasqlid    INTEGER;
  _isdba        BOOLEAN := false;

BEGIN
  SELECT rolsuper INTO _isdba FROM pg_roles WHERE (rolname=getEffectiveXtUser());

  IF (NOT (_isdba OR checkPrivilege('MaintainMetaSQL'))) THEN
    RAISE EXCEPTION '% does not have privileges to maintain MetaSQL statements in %.% (DBA=%)',
                getEffectiveXtUser(), TG_TABLE_SCHEMA, TG_TABLE_NAME, _isdba;
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    RAISE DEBUG 'update OLD %-%-%, NEW %-%-%',
                 OLD.metasql_group, OLD.metasql_name, OLD.metasql_grade,
                 NEW.metasql_group, NEW.metasql_name, NEW.metasql_grade;

    IF (NEW.metasql_name != OLD.metasql_name OR NEW.metasql_group != OLD.metasql_group OR NEW.metasql_grade != OLD.metasql_grade) THEN
      SELECT metasql_id INTO _metasqlid
      FROM metasql
      WHERE metasql_name=NEW.metasql_name AND metasql_group=NEW.metasql_group AND metasql_grade=NEW.metasql_grade;
      IF (FOUND) THEN
        RAISE EXCEPTION 'Cannot change the MetaSQL statement named %-%-% because another MetaSQL statement with that group, name and grade already exists.', NEW.metasql_group, NEW.metasql_name, NEW.metasql_grade;
      END IF;
    END IF;

  ELSIF (TG_OP = 'INSERT') THEN
    RAISE DEBUG 'insert NEW %-% %',
                 NEW.metasql_group, NEW.metasql_name, NEW.metasql_grade;
    SELECT metasql_id INTO _metasqlid
    FROM metasql
    WHERE metasql_name=NEW.metasql_name AND metasql_group=NEW.metasql_group AND metasql_grade=NEW.metasql_grade;
    IF (FOUND) THEN
      RAISE EXCEPTION 'The new MetaSQL statement %-% % conflicts with an existing statement.',
                      NEW.metasql_group, NEW.metasql_name, NEW.metasql_grade;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgprivaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgprivaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create privileges in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter privileges in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete privileges from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;


Function: public._pkgprivbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _privid       INTEGER;
  _debug        BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    IF (_debug) THEN
      RAISE NOTICE 'OLD.priv_name %, NEW.priv_name %',
                   OLD.priv_name, NEW.priv_name;
    END IF;

    IF (NEW.priv_name != OLD.priv_name) THEN
      SELECT priv_id INTO _privid FROM priv WHERE priv_name=NEW.priv_name;
      IF (FOUND) THEN
        RAISE EXCEPTION 'Cannot change privilege name % because another privilege with that name already exists.', NEW.priv_name;
      END IF;
    END IF;

  ELSIF (TG_OP = 'INSERT') THEN
    IF (_debug) THEN
      RAISE NOTICE 'inserting NEW.priv_name %', NEW.priv_name;
    END IF;
    SELECT priv_id INTO _privid FROM priv WHERE priv_name=NEW.priv_name;
    IF (FOUND) THEN
      RAISE EXCEPTION 'Cannot create new privilege % because another privilege with that name already exists.', NEW.priv_name;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    IF (_debug) THEN RAISE NOTICE 'deleting pkgpriv_id %', OLD.priv_id; END IF;
    DELETE FROM usrpriv WHERE usrpriv_priv_id=OLD.priv_id;
    DELETE FROM grppriv WHERE grppriv_priv_id=OLD.priv_id;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgreportaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgreportaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create report definitions in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter report definitions in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete report definitions from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;

Function: public._pkgreportbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _reportid     INTEGER;
  _debug        BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    IF (_debug) THEN
      RAISE NOTICE 'update OLD % %, NEW % %',
                   OLD.report_name, OLD.report_grade, NEW.report_name, NEW.report_grade;
    END IF;

    IF (NEW.report_name != OLD.report_name) THEN
      SELECT report_id INTO _reportid
      FROM report
      WHERE ((report_name=NEW.report_name)
        AND  (report_grade=NEW.report_grade));
      IF (FOUND) THEN
        RAISE EXCEPTION 'Cannot change report % % because another report with that name and grade already exists.', NEW.report_name, NEW.report_grade;
      END IF;
    END IF;

  ELSIF (TG_OP = 'INSERT') THEN
    IF (_debug) THEN
      RAISE NOTICE 'insert NEW % %', NEW.report_name, NEW.report_grade;
    END IF;
    SELECT report_id INTO _reportid
    FROM report
    WHERE ((report_name=NEW.report_name)
      AND  (report_grade=NEW.report_grade));
    IF (FOUND) THEN
      RAISE EXCEPTION 'Cannot create new report % % because another report with that name and grade already exists.', NEW.report_name, NEW.report_grade;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgscriptaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkgscriptaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create scripts in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter scripts in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete scripts from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;

Function: public._pkgscriptbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _scriptid     INTEGER;
  _debug        BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'INSERT') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkguiformaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._pkguiformaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pkgMayBeModified(TG_TABLE_SCHEMA)) THEN
    IF (TG_OP = 'DELETE') THEN
      RETURN OLD;
    ELSE
      RETURN NEW;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    RAISE EXCEPTION 'You may not create forms in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'UPDATE') THEN
    RAISE EXCEPTION 'You may not alter forms in packages except using the xTuple Updater utility';

  ELSIF (TG_OP = 'DELETE') THEN
    RAISE EXCEPTION 'You may not delete forms from packages. Try deleting or disabling the package.';

  END IF;

  RETURN NEW;
END;


Function: public._pkguiformbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _uiformid     INTEGER;
  _debug        BOOL := false;

BEGIN
  IF (TG_OP = 'UPDATE') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'INSERT') THEN
    RETURN NEW;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._poheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid 	INTEGER;
  _check	BOOLEAN;
  _maint        BOOLEAN := TRUE;

BEGIN

-- Check if we are doing maintenance
  IF (TG_OP = 'UPDATE') THEN
    IF ( (OLD.pohead_status           != NEW.pohead_status) OR
         (OLD.pohead_printed          != NEW.pohead_printed) ) THEN
      _maint := FALSE;
    END IF;
  END IF;

  -- Check
  IF ( (NOT _maint) AND (NOT checkPrivilege('MaintainPurchaseOrders'))
                    AND (NOT checkPrivilege('PostPurchaseOrders'))
                    AND (NOT checkPrivilege('PrintPurchaseOrders'))
                    AND (NOT checkPrivilege('PostVouchers')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Purchase Order.';
  END IF;

  IF ( _maint AND (NOT checkPrivilege('MaintainPurchaseOrders')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Purchase Order.';
  END IF;

  IF (TG_OP = 'INSERT') THEN
    --- clear the number from the issue cache
    PERFORM clearNumberIssue('PoNumber', NEW.pohead_number);
  END IF;

  IF ( (TG_OP = 'INSERT') OR (TG_op = 'UPDATE') ) THEN
    IF (NOT ISNUMERIC(NEW.pohead_number) AND NEW.pohead_saved) THEN
      RAISE EXCEPTION 'Purchase Order Number must be numeric.';
    END IF;
  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='POChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'P', NEW.pohead_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.pohead_terms_id <> NEW.pohead_terms_id) THEN
          PERFORM postComment( _cmnttypeid, 'P', NEW.pohead_id,
                               ('Terms Changed from "' || oldterms.terms_code || '" to "' || newterms.terms_code || '"') )
          FROM terms AS oldterms, terms AS newterms
          WHERE ( (oldterms.terms_id=OLD.pohead_terms_id)
           AND (newterms.terms_id=NEW.pohead_terms_id) );
        END IF;

      ELSIF (TG_OP = 'DELETE') THEN
        DELETE FROM comment
        WHERE ( (comment_source='P')
         AND (comment_source_id=OLD.pohead_id) );
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;

END;

Function: public._poheadtriggerafter()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (COALESCE(NEW.pohead_taxzone_id,-1) <> COALESCE(OLD.pohead_taxzone_id,-1)) THEN
    UPDATE poitem SET poitem_taxtype_id=getItemTaxType(itemsite_item_id,NEW.pohead_taxzone_id)
    FROM itemsite 
    WHERE ((itemsite_id=poitem_itemsite_id)
     AND (poitem_pohead_id=NEW.pohead_id));
  END IF;

  -- Do not update closed poitems
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.pohead_status != NEW.pohead_status) THEN
      UPDATE poitem
      SET poitem_status=NEW.pohead_status
      WHERE ( (poitem_pohead_id=NEW.pohead_id)
        AND   (poitem_status <> 'C') );
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._poitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid 	INTEGER;
  _status      	CHAR(1);
  _check      	BOOLEAN;
  _cnt     	INTEGER;
  _s 		RECORD;
BEGIN

  -- Check
  IF ( (TG_OP = 'UPDATE') AND
       (NOT checkPrivilege('MaintainPurchaseOrders')) AND
       (NOT checkPrivilege('ChangePurchaseOrderQty')) AND
       (NOT checkPrivilege('EnterReceipts')) AND
       (NOT checkPrivilege('PostVouchers')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Purchase Order.';
  END IF;
  IF ( ( (TG_OP = 'INSERT') OR (TG_OP = 'DELETE') ) AND (NOT checkPrivilege('MaintainPurchaseOrders')) ) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Purchase Order.';
  END IF;

  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
    SELECT pohead_status INTO _status
    FROM pohead
    WHERE (pohead_id=NEW.poitem_pohead_id);

    IF (NEW.poitem_itemsite_id=-1) THEN
      NEW.poitem_itemsite_id := NULL;
    END IF;
    IF (NEW.poitem_expcat_id=-1) THEN
      NEW.poitem_expcat_id := NULL;
    END IF;

    IF (NEW.poitem_itemsite_id IS NOT NULL AND NEW.poitem_expcat_id IS NOT NULL) THEN
      RAISE EXCEPTION 'A purchase order line may not include both an inventory and non-inventory item';
    ELSIF (NEW.poitem_itemsite_id IS NULL AND NEW.poitem_expcat_id IS NULL) THEN
      RAISE EXCEPTION 'A purchase order line must specify either an inventory item or a non-inventory expense category';
    ELSIF (NEW.poitem_qty_ordered IS NULL) THEN
      RAISE EXCEPTION 'A purchase order line must specify a quantity';
    ELSIF (COALESCE(NEW.poitem_itemsite_id,-1) != -1) THEN
      SELECT (COUNT(item_id)=1) INTO _check
      FROM itemsite, item
      WHERE ((itemsite_id=NEW.poitem_itemsite_id)
      AND (itemsite_item_id=item_id)
      AND (item_type IN ('P','O','M','T')));
      IF NOT (_check) THEN
        RAISE EXCEPTION 'The item is not a purchasable item type';
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    IF (_status='C') THEN
      RAISE EXCEPTION 'New lines may not be inserted into a closed purchase order';
    END IF;
    
    --Fetch and apply default item source data if applicable    
    IF ((NEW.poitem_itemsrc_id IS NULL) AND (NEW.poitem_itemsite_id IS NOT NULL)) THEN
      IF (NEW.poitem_itemsrc_id IS NULL) THEN
        SELECT COUNT(itemsrc_id)  INTO _cnt
        FROM pohead,itemsrc,itemsite
        WHERE ((pohead_id=NEW.poitem_pohead_id)
        AND (pohead_vend_id=itemsrc_vend_id)
        AND (itemsite_id=NEW.poitem_itemsite_id)
        AND (itemsite_item_id=itemsrc_item_id));

        IF (_cnt = 1) THEN
          -- We found the one and only item source, so populate data for it
          SELECT itemsrc.* INTO _s
          FROM pohead,itemsrc,itemsite
          WHERE ((pohead_id=NEW.poitem_pohead_id)
          AND (pohead_vend_id=itemsrc_vend_id)
          AND (itemsite_id=NEW.poitem_itemsite_id)
          AND (itemsite_item_id=itemsrc_item_id));
          IF (FOUND) THEN
            NEW.poitem_itemsrc_id 		:= _s.itemsrc_id;
            NEW.poitem_vend_uom            	:= _s.itemsrc_vend_uom;
            NEW.poitem_invvenduomratio    	:= _s.itemsrc_invvendoruomratio;
            NEW.poitem_duedate			:= COALESCE(NEW.poitem_duedate, CURRENT_DATE + _s.itemsrc_leadtime);
            NEW.poitem_vend_item_number 	:= COALESCE(NEW.poitem_vend_item_number,_s.itemsrc_vend_item_number);
            NEW.poitem_vend_item_descrip   	:= COALESCE(NEW.poitem_vend_item_descrip,_s.itemsrc_vend_item_descrip);
            NEW.poitem_manuf_name		:= COALESCE(NEW.poitem_manuf_name,_s.itemsrc_manuf_name);
            NEW.poitem_manuf_item_number	:= COALESCE(NEW.poitem_manuf_item_number, _s.itemsrc_manuf_item_number);
            NEW.poitem_manuf_item_descrip	:= COALESCE(NEW.poitem_manuf_item_descrip, _s.itemsrc_manuf_item_descrip);
          END IF;
        ELSIF (_cnt > 1) THEN
          -- There are multiple sources, see if there is an exact match with provided vendor info.
          SELECT itemsrc.* INTO _s
          FROM pohead,itemsrc,itemsite
          WHERE ((pohead_id=NEW.poitem_pohead_id)
          AND (pohead_vend_id=itemsrc_vend_id)
          AND (itemsite_id=NEW.poitem_itemsite_id)
          AND (itemsite_item_id=itemsrc_item_id)
          AND (NEW.poitem_vend_item_number=itemsrc_vend_item_number)
          AND (COALESCE(NEW.poitem_manuf_name,'')=COALESCE(itemsrc_manuf_name,''))
          AND (COALESCE(NEW.poitem_manuf_item_number,'')=COALESCE(itemsrc_manuf_item_number,'')));
          IF (FOUND) THEN
            NEW.poitem_itemsrc_id 		:= _s.itemsrc_id;
            NEW.poitem_vend_uom            	:= _s.itemsrc_vend_uom;
            NEW.poitem_invvenduomratio    	:= _s.itemsrc_invvendoruomratio;
            NEW.poitem_duedate			:= COALESCE(NEW.poitem_duedate, CURRENT_DATE + _s.itemsrc_leadtime);
            NEW.poitem_vend_item_descrip   	:= COALESCE(NEW.poitem_vend_item_descrip,_s.itemsrc_vend_item_descrip);
            NEW.poitem_manuf_item_descrip	:= COALESCE(NEW.poitem_manuf_item_descrip, _s.itemsrc_manuf_item_descrip);
          END IF;
        END IF;
      END IF;
    END IF;

    IF (NEW.poitem_duedate IS NULL) THEN
      RAISE EXCEPTION  'A due date is required';
    END IF;
    
    --Set defaults
    NEW.poitem_linenumber    		:= COALESCE(NEW.poitem_linenumber,(
						SELECT COALESCE(MAX(poitem_linenumber),0) + 1
						FROM poitem
						WHERE (poitem_pohead_id=NEW.poitem_pohead_id)));
    NEW.poitem_status                  := _status;
    NEW.poitem_invvenduomratio 	:= COALESCE(NEW.poitem_invvenduomratio,1);
    IF (NEW.poitem_invvenduomratio = 0.0) THEN
      NEW.poitem_invvenduomratio = 1.0;
    END IF;
    NEW.poitem_vend_item_number 	:= COALESCE(NEW.poitem_vend_item_number,'');
    NEW.poitem_vend_item_descrip   	:= COALESCE(NEW.poitem_vend_item_descrip,'');
    NEW.poitem_unitprice       	:= COALESCE(NEW.poitem_unitprice,(
						SELECT currToCurr(itemsrcp_curr_id, pohead_curr_id, itemsrcp_price, pohead_orderdate)
						FROM itemsrcp, pohead
						WHERE ( (itemsrcp_itemsrc_id=NEW.poitem_itemsrc_id)
						AND (itemsrcp_qtybreak <= NEW.poitem_qty_ordered)
						AND (pohead_id=NEW.poitem_pohead_id) ) 
						ORDER BY itemsrcp_qtybreak DESC
						LIMIT 1), 0);
    NEW.poitem_stdcost			:= COALESCE(NEW.poitem_stdcost,(
						SELECT stdcost(itemsite_item_id)
						FROM itemsite
						WHERE (itemsite_id=NEW.poitem_itemsite_id)));
    NEW.poitem_bom_rev_id		:= COALESCE(NEW.poitem_bom_rev_id,(
						SELECT getActiveRevId('BOM',itemsite_item_id)
						FROM itemsite
						WHERE (itemsite_id=NEW.poitem_itemsite_id)));
    NEW.poitem_boo_rev_id		:= COALESCE(NEW.poitem_boo_rev_id,(
						SELECT getActiveRevId('BOO',itemsite_item_id)
						FROM itemsite
						WHERE (itemsite_id=NEW.poitem_itemsite_id)));
    NEW.poitem_comments		:= COALESCE(NEW.poitem_comments,'');
    NEW.poitem_freight			:= COALESCE(NEW.poitem_freight,0);
    NEW.poitem_qty_received		:= 0;
    NEW.poitem_qty_returned		:= 0;
    NEW.poitem_qty_vouchered		:= 0;
      
--   Insert Event Start
       
    INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
                     'P', NEW.poitem_id, itemsite_warehous_id, (pohead_number || '-' || NEW.poitem_linenumber || ': ' || item_number)
    FROM evntnot, evnttype, itemsite, item, pohead
     WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (itemsite_id=NEW.poitem_itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (NEW.poitem_pohead_id=pohead_id)
     AND (NEW.poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
     AND (evnttype_name='POitemCreate') );

--   Insert Event End

  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='POChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'P', NEW.poitem_pohead_id, ('Created Line #' || NEW.poitem_linenumber::TEXT));
        PERFORM postComment(_cmnttypeid, 'PI', NEW.poitem_id, 'Created');
      ELSIF (TG_OP = 'UPDATE') THEN
        IF (NEW.poitem_qty_ordered <> OLD.poitem_qty_ordered) THEN
          PERFORM postComment( _cmnttypeid, 'PI', NEW.poitem_id,
                               ( 'Qty. Ordered Changed from ' || formatQty(OLD.poitem_qty_ordered) ||
                                 ' to ' || formatQty(NEW.poitem_qty_ordered ) ) );
        END IF;
        IF (NEW.poitem_unitprice <> OLD.poitem_unitprice) THEN
          PERFORM postComment( _cmnttypeid, 'PI', NEW.poitem_id,
                               ( 'Unit Price Changed from ' || formatPurchPrice(OLD.poitem_unitprice) ||
                                 ' to ' || formatPurchPrice(NEW.poitem_unitprice ) ) );
        END IF;
        IF (NEW.poitem_duedate <> OLD.poitem_duedate) THEN
          PERFORM postComment( _cmnttypeid, 'PI', NEW.poitem_id,
                               ( 'Due Date Changed from ' || formatDate(OLD.poitem_duedate) ||
                                 ' to ' || formatDate(NEW.poitem_duedate ) ) );
        END IF;
        IF (COALESCE(OLD.poitem_taxtype_id, -1) <> COALESCE(NEW.poitem_taxtype_id, -1)) THEN
          PERFORM postComment( _cmnttypeid, 'PI', NEW.poitem_id,
                               ( 'Tax Type Changed from "' ||
                                 COALESCE((SELECT taxtype_name FROM taxtype WHERE taxtype_id=OLD.poitem_taxtype_id), 'None') ||
                                 '" (' || COALESCE(OLD.poitem_taxtype_id, 0) ||
                                 ') to "' ||
                                 COALESCE((SELECT taxtype_name FROM taxtype WHERE taxtype_id=NEW.poitem_taxtype_id), 'None') ||
                                 '" (' || COALESCE(NEW.poitem_taxtype_id, 0) || ')' ) );
        END IF;
        IF (NEW.poitem_status <> OLD.poitem_status) THEN
          IF (NEW.poitem_status = 'C') THEN
            PERFORM postComment(_cmnttypeid, 'PI', NEW.poitem_id, 'Closed');
          ELSIF (NEW.poitem_status = 'O') THEN
            PERFORM postComment(_cmnttypeid, 'PI', NEW.poitem_id, 'Opened');
          END IF;
        END IF;

      ELSIF (TG_OP = 'DELETE') THEN
        PERFORM postComment(_cmnttypeid, 'P', OLD.poitem_pohead_id, ('Deleted Line #' || OLD.poitem_linenumber::TEXT));
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    IF (EXISTS(SELECT recv_id
               FROM recv
               WHERE ((recv_order_type='PO')
                  AND (recv_orderitem_id=OLD.poitem_id)
                  AND (recv_qty>0)))) THEN
      RAISE EXCEPTION 'Cannot delete an P/O Item which has been received';
    END IF;

    DELETE FROM comment
     WHERE ( (comment_source='PI')
       AND   (comment_source_id=OLD.poitem_id) );

    DELETE FROM charass
     WHERE ((charass_target_type='PI')
       AND  (charass_target_id=OLD.poitem_id));

    IF (OLD.poitem_status = 'O') THEN
      IF ( (SELECT (count(*) < 1)
              FROM poitem
             WHERE ((poitem_pohead_id=OLD.poitem_pohead_id)
               AND  (poitem_id != OLD.poitem_id)
               AND  (poitem_status <> 'C')) ) ) THEN
        UPDATE pohead SET pohead_status = 'C'
         WHERE ((pohead_id=OLD.poitem_pohead_id)
           AND  (pohead_status='O'));
      END IF;
    END IF;

    RETURN OLD;
  ELSE
    IF (TG_OP = 'UPDATE') THEN

      IF (NEW.poitem_itemsite_id != OLD.poitem_itemsite_id) THEN
        RAISE EXCEPTION 'You may not change the item site for a line item.';
      ELSIF (NEW.poitem_expcat_id != OLD.poitem_expcat_id) THEN
        RAISE EXCEPTION 'You may not change the expense category for a line item.';
      END IF;
    
      IF (OLD.poitem_status <> NEW.poitem_status) THEN
        IF ( (SELECT (count(*) < 1)
                FROM poitem
               WHERE ((poitem_pohead_id=NEW.poitem_pohead_id)
                 AND  (poitem_id != NEW.poitem_id)
                 AND  (poitem_status<>'C')) ) AND (NEW.poitem_status='C') ) THEN
          UPDATE pohead SET pohead_status = 'C'
           WHERE ((pohead_id=NEW.poitem_pohead_id)
             AND  (pohead_status='O'));
        ELSE
          UPDATE pohead SET pohead_status = 'O'
           WHERE ((pohead_id=NEW.poitem_pohead_id)
             AND  (pohead_status='C'));
        END IF;
      END IF;
    END IF;

    RETURN NEW;
  END IF;

END;

Function: public._prjaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
BEGIN

--  Cache the cmnttype_id for ChangeLog
  SELECT cmnttype_id INTO _cmnttypeid
  FROM cmnttype
  WHERE (cmnttype_name='ChangeLog');
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Comment type ChangeLog not found';
  END IF;

  IF (TG_OP = 'INSERT') THEN
    PERFORM postComment(_cmnttypeid, 'J', NEW.prj_id, 'Created');

  ELSIF (TG_OP = 'UPDATE') THEN
    IF (OLD.prj_start_date <> NEW.prj_start_date) THEN
      PERFORM postComment( _cmnttypeid, 'J', NEW.prj_id,
                           ('Start Date Changed from ' || formatDate(OLD.prj_start_date) || ' to ' || formatDate(NEW.prj_start_date)) );
    END IF;
    IF (OLD.prj_due_date <> NEW.prj_due_date) THEN
      PERFORM postComment( _cmnttypeid, 'J', NEW.prj_id,
                           ('Due Date Changed from ' || formatDate(OLD.prj_due_date) || ' to ' || formatDate(NEW.prj_due_date)) );
    END IF;
    IF (OLD.prj_assigned_date <> NEW.prj_assigned_date) THEN
      PERFORM postComment( _cmnttypeid, 'J', NEW.prj_id,
                           ('Assigned Date Changed from ' || formatDate(OLD.prj_assigned_date) || ' to ' || formatDate(NEW.prj_assigned_date)) );
    END IF;
    IF (OLD.prj_completed_date <> NEW.prj_completed_date) THEN
      PERFORM postComment( _cmnttypeid, 'J', NEW.prj_id,
                           ('Completed Date Changed from ' || formatDate(OLD.prj_completed_date) || ' to ' || formatDate(NEW.prj_completed_date)) );
    END IF;

  END IF;

  RETURN NEW;
END;

Function: public._prjbeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _recurid     INTEGER;
  _newparentid INTEGER;
BEGIN

  IF (TG_OP = 'DELETE') THEN
    SELECT recur_id INTO _recurid
      FROM recur
     WHERE ((recur_parent_id=OLD.prj_id)
        AND (recur_parent_type='J'));

    IF (_recurid IS NOT NULL) THEN
      SELECT MIN(prj_id) INTO _newparentid
        FROM prj
       WHERE ((prj_recurring_prj_id=OLD.prj_id)
          AND (prj_id!=OLD.prj_id));

      -- client is responsible for warning about deleting a recurring prj
      IF (_newparentid IS NULL) THEN
        DELETE FROM recur WHERE recur_id=_recurid;
      ELSE
        UPDATE recur SET recur_parent_id=_newparentid
         WHERE recur_id=_recurid;
      END IF;

    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._prjtaskaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
BEGIN

  SELECT cmnttype_id INTO _cmnttypeid
  FROM cmnttype
  WHERE (cmnttype_name='ChangeLog');
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Comment type ChangeLog not found';
  END IF;

  IF (TG_OP = 'INSERT') THEN
    PERFORM postComment(_cmnttypeid, 'TA', NEW.prjtask_id, 'Created');

  ELSIF (TG_OP = 'UPDATE') THEN
    IF (OLD.prjtask_start_date <> NEW.prjtask_start_date) THEN
      PERFORM postComment( _cmnttypeid, 'TA', NEW.prjtask_id,
                           ('Start Date Changed from ' || formatDate(OLD.prjtask_start_date) || ' to ' || formatDate(NEW.prjtask_start_date)) );
    END IF;
    IF (OLD.prjtask_due_date <> NEW.prjtask_due_date) THEN
      PERFORM postComment( _cmnttypeid, 'TA', NEW.prjtask_id,
                           ('Due Date Changed from ' || formatDate(OLD.prjtask_due_date) || ' to ' || formatDate(NEW.prjtask_due_date)) );
    END IF;
    IF (OLD.prjtask_assigned_date <> NEW.prjtask_assigned_date) THEN
      PERFORM postComment( _cmnttypeid, 'TA', NEW.prjtask_id,
                           ('Assigned Date Changed from ' || formatDate(OLD.prjtask_assigned_date) || ' to ' || formatDate(NEW.prjtask_assigned_date)) );
    END IF;
    IF (OLD.prjtask_completed_date <> NEW.prjtask_completed_date) THEN
      PERFORM postComment( _cmnttypeid, 'TA', NEW.prjtask_id,
                           ('Completed Date Changed from ' || formatDate(OLD.prjtask_completed_date) || ' to ' || formatDate(NEW.prjtask_completed_date)) );
    END IF;
    IF (OLD.prjtask_hours_actual != NEW.prjtask_hours_actual) THEN
      PERFORM postComment(_cmnttypeid, 'TA', NEW.prjtask_id, 
          'Actual Hours changed from ' || formatQty(OLD.prjtask_hours_actual) || ' to ' || formatQty(NEW.prjtask_hours_actual));
    END IF;
    IF (OLD.prjtask_exp_actual != NEW.prjtask_exp_actual) THEN
      PERFORM postComment(_cmnttypeid, 'TA', NEW.prjtask_id, 
          'Actual Expense changed from ' || formatQty(OLD.prjtask_exp_actual) || ' to ' || formatQty(NEW.prjtask_exp_actual));
    END IF;

  END IF;
  
  RETURN NEW;
END;

Function: public._prjtasktrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  --  Checks
  IF (NEW.prjtask_owner_username=getEffectiveXtUser()) THEN
    IF (NOT checkPrivilege('MaintainAllProjects') AND NOT checkPrivilege('MaintainPersonalProjects')) THEN
      RAISE EXCEPTION 'You do not have privileges to maintain Projects.';
    END IF;
  ELSIF (NOT checkPrivilege('MaintainAllProjects')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Projects.';
  ELSIF (LENGTH(COALESCE(NEW.prjtask_number,'')) = 0) THEN
    RAISE EXCEPTION 'You must ender a valid number.';
  ELSIF (LENGTH(COALESCE(NEW.prjtask_name,'')) = 0) THEN
    RAISE EXCEPTION 'You must ender a valid name.';	
  END IF;

  RETURN NEW;
END;

Function: public._prospectafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF EXISTS(SELECT 1 FROM quhead WHERE quhead_cust_id = OLD.prospect_id) AND
     NOT EXISTS (SELECT 1 FROM custinfo WHERE cust_id = OLD.prospect_id) THEN
    RAISE EXCEPTION '[xtuple: deleteProspect, -1]';
  END IF;

  IF (fetchMetricBool('ProspectChangeLog')) THEN
    PERFORM postComment(cmnttype_id, 'PSPCT', OLD.prospect_id,
                        'Deleted "' || OLD.prospect_number || '"')
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');
  END IF;

  RETURN OLD;
END;

Function: public._prospectaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid   INTEGER;
  _custid       INTEGER;
  _prospectid   INTEGER;

BEGIN

  IF (TG_OP = 'INSERT') THEN
    SELECT crmacct_cust_id, crmacct_prospect_id INTO _custid, _prospectid
      FROM crmacct
     WHERE crmacct_number=NEW.prospect_number;

    IF (_custid > 0 AND _custid != _prospectid) THEN
      RAISE EXCEPTION '[xtuple: createProspect, -2]';
    END IF;

    IF (_prospectid > 0) THEN
      RAISE EXCEPTION '[xtuple: createProspect, -3]';
    END IF;

    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_prospect_id=NEW.prospect_id,
                         crmacct_cust_id=NULL,
                         crmacct_name=NEW.prospect_name
       WHERE crmacct_number=NEW.prospect_number;
      IF (FOUND) THEN
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,      crmacct_name,
                            crmacct_active,      crmacct_type,
                            crmacct_prospect_id, crmacct_cntct_id_1
                  ) VALUES (NEW.prospect_number, NEW.prospect_name,
                            NEW.prospect_active, 'O',
                            NEW.prospect_id,     NEW.prospect_cntct_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    /* TODO: default characteristic assignments based on what? */

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.prospect_number
    WHERE ((crmacct_prospect_id=NEW.prospect_id)
      AND  (crmacct_number!=NEW.prospect_number));

    UPDATE crmacct SET crmacct_name = NEW.prospect_name
    WHERE ((crmacct_prospect_id=NEW.prospect_id)
      AND  (crmacct_name!=NEW.prospect_name));

  END IF;

  IF (fetchMetricBool('ProspectChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.prospect_active <> NEW.prospect_active) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              CASE WHEN NEW.prospect_active THEN 'Activated'
                                   ELSE 'Deactivated' END);
        END IF;

        IF (OLD.prospect_number <> NEW.prospect_number) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Number changed from "' || OLD.prospect_number ||
                              '" to "' || NEW.prospect_number || '"');
        END IF;

        IF (OLD.prospect_name <> NEW.prospect_name) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Name changed from "' || OLD.prospect_name ||
                              '" to "' || NEW.prospect_name || '"');
        END IF;

        IF (OLD.prospect_cntct_id <> NEW.prospect_cntct_id) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Contact changed from "' ||
                              formatCntctName(OLD.prospect_cntct_id) || '" to "' ||
                              formatCntctName(NEW.prospect_cntct_id) || '"');
        END IF;

        IF (OLD.prospect_taxauth_id <> NEW.prospect_taxauth_id) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Tax Authority changed from "' ||
                              (SELECT taxauth_code FROM taxauth
                                WHERE taxauth_id=OLD.prospect_taxauth_id) ||
                              '" to "' ||
                              (SELECT taxauth_code FROM taxauth
                                WHERE taxauth_id=NEW.prospect_taxauth_id) || '"');
        END IF;

        IF (OLD.prospect_salesrep_id <> NEW.prospect_salesrep_id) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Sales Rep changed from "' ||
                              (SELECT salesrep_number FROM salesrep
                               WHERE salesrep_id=OLD.prospect_salesrep_id) ||
                              '" to "' ||
                              (SELECT salesrep_number FROM salesrep
                               WHERE salesrep_id=NEW.prospect_salesrep_id) || '"');
        END IF;

        IF (OLD.prospect_warehous_id <> NEW.prospect_warehous_id) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Warehouse changed from "' ||
                              (SELECT warehous_code FROM whsinfo
                                WHERE warehous_id=OLD.prospect_warehous_id) ||
                              '" to "' ||
                              (SELECT warehous_code FROM whsinfo
                                WHERE warehous_id=NEW.prospect_warehous_id) || '"');
        END IF;

        IF (OLD.prospect_taxzone_id <> NEW.prospect_taxzone_id) THEN
          PERFORM postComment(_cmnttypeid, 'PSPCT', NEW.prospect_id,
                              'Tax Zone changed from "' ||
                              (SELECT taxzone_code FROM taxzone
                                WHERE taxzone_id=OLD.prospect_taxzone_id) || '" to "' ||
                              (SELECT taxzone_code FROM taxzone
                                WHERE taxzone_id=NEW.prospect_taxzone_id) || '"');
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._prospectbeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainProspectMasters')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Prospects.';
  END IF;

  UPDATE crmacct SET crmacct_prospect_id = NULL
   WHERE crmacct_prospect_id = OLD.prospect_id;

  RETURN OLD;
END;

Function: public._prospecttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainProspectMasters')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Prospects.';
  END IF;

  IF (NEW.prospect_number IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Prospect Number.';
  END IF;

  NEW.prospect_number := UPPER(NEW.prospect_number);

  RETURN NEW;
END;

Function: public._prtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/EULA for the full text of the software license.
BEGIN
  --- clear the number from the issue cache
  PERFORM clearNumberIssue('PrNumber', NEW.pr_number);

  RETURN NEW;
END;

Function: public._quheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _oldHoldType TEXT;
  _newHoldType TEXT;
  _p RECORD;
  _a RECORD;
  _w RECORD;
  _shiptoId INTEGER;
  _addrId INTEGER;
  _prjId INTEGER;
  _check BOOLEAN;
  _numGen CHAR(1);

BEGIN

  --  Checks
  SELECT checkPrivilege('MaintainQuotes') INTO _check;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Quotes.';
  END IF;

  -- If this is imported, check the quote number
  IF (TG_OP = 'INSERT') THEN
    IF (NEW.quhead_imported) THEN
      SELECT fetchMetricText('QUNumberGeneration') INTO _numGen;
      IF ((NEW.quhead_number IS NULL) AND (_numGen='M')) THEN
        RAISE EXCEPTION 'You must supply a Quote Number.';
      ELSE
        IF ((NEW.quhead_number IS NOT NULL) AND (_numGen='A')) THEN
          RAISE EXCEPTION 'You may not supply a new Quote Number xTuple will generate the number.';
        ELSE
          IF ((NEW.quhead_number IS NULL) AND (_numGen='O')) THEN
            SELECT fetchqunumber() INTO NEW.quhead_number;
          ELSE
            IF (NEW.quhead_number IS NULL) THEN
              SELECT fetchsonumber() INTO NEW.quhead_number;
            END IF;
          END IF;
        END IF;
      END IF;
    END IF;
    
    IF (fetchMetricText('QUNumberGeneration') IN ('A','O')) THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('QuNumber', NEW.quhead_number);
    ELSIF (fetchMetricText('QUNumberGeneration') = 'S') THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('SoNumber', NEW.quhead_number);
    END IF;
    
  ELSE
    IF (TG_OP = 'UPDATE') THEN
       IF (NEW.quhead_number <> OLD.quhead_number) THEN
         RAISE EXCEPTION 'The order number may not be changed.';
       END IF;
    END IF;
  END IF;

  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    -- Get Customer data
    IF (NEW.quhead_shipto_id IS NULL) THEN
      SELECT * INTO _p FROM (
      SELECT cust_number,cust_usespos,cust_blanketpos,cust_ffbillto,
	     cust_ffshipto,cust_name,cust_salesrep_id,cust_terms_id,cust_shipvia,
	     cust_commprcnt,cust_curr_id,cust_taxzone_id,
  	     addr_line1,addr_line2,addr_line3,addr_city,addr_state,addr_postalcode,addr_country,
	     shipto_id,shipto_addr_id,shipto_name,shipto_salesrep_id,shipto_shipvia,
	     shipto_shipchrg_id,shipto_shipform_id,shipto_commission,shipto_taxzone_id
      FROM custinfo
        LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
        LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
        LEFT OUTER JOIN shiptoinfo ON ((cust_id=shipto_cust_id) AND shipto_default)
      WHERE (cust_id=NEW.quhead_cust_id)
      UNION
      SELECT prospect_number,false,false,true,
	     true,prospect_name,prospect_salesrep_id,null,null,
	     null,null,prospect_taxzone_id,
  	     addr_line1,addr_line2,addr_line3,addr_city,addr_state,addr_postalcode,addr_country,
	     null,null,null,null,null,
	     null,null,null,null
      FROM prospect
        LEFT OUTER JOIN cntct ON (prospect_cntct_id=cntct_id)
        LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
      WHERE (prospect_id=NEW.quhead_cust_id)) AS data;
    ELSE
      SELECT cust_creditstatus,cust_number,cust_usespos,cust_blanketpos,cust_ffbillto,
	     cust_ffshipto,cust_name,cust_salesrep_id,cust_terms_id,cust_shipvia,
	     cust_shipchrg_id,cust_shipform_id,cust_commprcnt,cust_curr_id,cust_taxzone_id,
  	     addr_line1,addr_line2,addr_line3,addr_city,addr_state,addr_postalcode,addr_country,
	     shipto_id,shipto_addr_id,shipto_name,shipto_salesrep_id,shipto_shipvia,
	     shipto_shipchrg_id,shipto_shipform_id,shipto_commission,shipto_taxzone_id INTO _p
      FROM shiptoinfo,custinfo
        LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
        LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
      WHERE ((cust_id=NEW.quhead_cust_id)
      AND (shipto_id=shipto_id));
    END IF;

    -- If there is customer data, then we can get to work
    IF (FOUND) THEN
      -- Only check PO number for imports because UI checks when whole quote is saved
      IF (TG_OP = 'INSERT') THEN
          -- Set to defaults if values not provided
          NEW.quhead_shipto_id		:= COALESCE(NEW.quhead_shipto_id,_p.shipto_id);
	  NEW.quhead_salesrep_id 	:= COALESCE(NEW.quhead_salesrep_id,_p.shipto_salesrep_id,_p.cust_salesrep_id);
          NEW.quhead_terms_id		:= COALESCE(NEW.quhead_terms_id,_p.cust_terms_id);
          NEW.quhead_shipvia		:= COALESCE(NEW.quhead_shipvia,_p.shipto_shipvia,_p.cust_shipvia);
          NEW.quhead_commission		:= COALESCE(NEW.quhead_commission,_p.shipto_commission,_p.cust_commprcnt);
          NEW.quhead_quotedate		:= COALESCE(NEW.quhead_quotedate,current_date);
          NEW.quhead_packdate		:= COALESCE(NEW.quhead_packdate,NEW.quhead_quotedate);
          NEW.quhead_curr_id		:= COALESCE(NEW.quhead_curr_id,_p.cust_curr_id,basecurrid());
          NEW.quhead_taxzone_id		:= COALESCE(NEW.quhead_taxzone_id,_p.shipto_taxzone_id,_p.cust_taxzone_id);
          NEW.quhead_freight		:= COALESCE(NEW.quhead_freight,0);
          NEW.quhead_custponumber	:= COALESCE(NEW.quhead_custponumber,'');
          NEW.quhead_ordercomments	:= COALESCE(NEW.quhead_ordercomments,'');
          NEW.quhead_shipcomments	:= COALESCE(NEW.quhead_shipcomments,'');
          NEW.quhead_shiptophone	:= COALESCE(NEW.quhead_shiptophone,'');
          NEW.quhead_misc		:= COALESCE(NEW.quhead_misc,0);
          NEW.quhead_misc_descrip	:= COALESCE(NEW.quhead_misc_descrip,'');

          IF ((NEW.quhead_warehous_id IS NULL) OR (NEW.quhead_fob IS NULL)) THEN
            IF (NEW.quhead_warehous_id IS NULL) THEN
              SELECT warehous_id,warehous_fob INTO _w
              FROM usrpref, whsinfo
              WHERE ((warehous_id=CAST(usrpref_value AS INTEGER))
                AND (warehous_shipping)
                AND (warehous_active)
                AND (usrpref_username=getEffectiveXtUser())
                AND (usrpref_name='PreferredWarehouse'));
            ELSE
              SELECT warehous_id,warehous_fob INTO _w
              FROM whsinfo
              WHERE (warehous_id=NEW.quhead_warehous_id);
            END IF;
            
            IF (FOUND) THEN
              NEW.quhead_warehous_id 	:= COALESCE(NEW.quhead_warehous_id,_w.warehous_id);
              NEW.quhead_fob		:= COALESCE(NEW.quhead_fob,_w.warehous_fob);
            END IF;
          END IF;
      END IF;
      
      --Auto create project if applicable
      IF ((TG_OP = 'INSERT') AND (NEW.quhead_prj_id=-1)) THEN
        SELECT fetchMetricBool('AutoCreateProjectsForOrders') INTO _check;
        IF (_check) THEN
          SELECT NEXTVAL('prj_prj_id_seq') INTO _prjId;
          NEW.quhead_prj_id := _prjId;
          INSERT INTO prj (prj_id, prj_number, prj_name, prj_descrip, prj_so, prj_wo, prj_po)
               VALUES(_prjId, NEW.quhead_number, NEW.quhead_number, 'Auto Generated Project from Quote.', TRUE, TRUE, TRUE);
        END IF;
      END IF;

      -- Deal with Billing Address
      IF (TG_OP = 'INSERT') THEN
        IF (_p.cust_ffbillto) THEN
          -- If they didn't supply data, we'll put in the bill to address
          NEW.quhead_billtoname=COALESCE(NEW.quhead_billtoname,_p.cust_name,'');
          NEW.quhead_billtoaddress1=COALESCE(NEW.quhead_billtoaddress1,_p.addr_line1,'');
          NEW.quhead_billtoaddress2=COALESCE(NEW.quhead_billtoaddress2,_p.addr_line2,'');
          NEW.quhead_billtoaddress3=COALESCE(NEW.quhead_billtoaddress3,_p.addr_line3,'');    
          NEW.quhead_billtocity=COALESCE(NEW.quhead_billtocity,_p.addr_city,''); 
          NEW.quhead_billtostate=COALESCE(NEW.quhead_billtostate,_p.addr_state,'');
          NEW.quhead_billtozip=COALESCE(NEW.quhead_billtozip,_p.addr_postalcode,'');
          NEW.quhead_billtocountry=COALESCE(NEW.quhead_billtocountry,_p.addr_country,'');   
        ELSE
          -- Free form not allowed, we're going to put in the address regardless
          NEW.quhead_billtoname=COALESCE(_p.cust_name,'');
          NEW.quhead_billtoaddress1=COALESCE(_p.addr_line1,'');
          NEW.quhead_billtoaddress2=COALESCE(_p.addr_line2,'');
          NEW.quhead_billtoaddress3=COALESCE(_p.addr_line3,'');    
          NEW.quhead_billtocity=COALESCE(_p.addr_city,''); 
          NEW.quhead_billtostate=COALESCE(_p.addr_state,'');
          NEW.quhead_billtozip=COALESCE(_p.addr_postalcode,'');
          NEW.quhead_billtocountry=COALESCE(_p.addr_country,'');
        END IF;
      END IF;

      -- Now let's look at Shipto Address
      -- If there's nothing in the address fields and there is a shipto id 
      -- or there is a default address available, let's put in some shipto address data
      IF ((TG_OP = 'INSERT') 
       AND NOT ((NEW.quhead_shipto_id IS NULL) AND NOT _p.cust_ffshipto)
       AND (NEW.quhead_shiptoname IS NULL)
       AND (NEW.quhead_shiptoaddress1 IS NULL)
       AND (NEW.quhead_shiptoaddress2 IS NULL)
       AND (NEW.quhead_shiptoaddress3 IS NULL)
       AND (NEW.quhead_shiptocity IS NULL)
       AND (NEW.quhead_shiptostate IS NULL)
       AND (NEW.quhead_shiptocountry IS NULL)) THEN
        IF ((NEW.quhead_shipto_id IS NULL) AND (_p.shipto_id IS NOT NULL)) THEN
          _shiptoId := _p.shipto_addr_id;
        ELSE
          _shiptoId := NEW.quhead_shipto_id;
        END IF;

        SELECT * INTO _a 
        FROM shiptoinfo, addr 
        WHERE ((shipto_id=_shiptoId)
        AND (addr_id=shipto_addr_id));

        NEW.quhead_shiptoname := COALESCE(_p.shipto_name,'');
        NEW.quhead_shiptoaddress1 := COALESCE(_a.addr_line1,'');
        NEW.quhead_shiptoaddress2 := COALESCE(_a.addr_line2,'');
        NEW.quhead_shiptoaddress3 := COALESCE(_a.addr_line3,'');    
        NEW.quhead_shiptocity := COALESCE(_a.addr_city,''); 
        NEW.quhead_shiptostate := COALESCE(_a.addr_state,'');
        NEW.quhead_shiptozipcode := COALESCE(_a.addr_postalcode,'');
        NEW.quhead_shiptocountry := COALESCE(_a.addr_country,'');
      ELSE
        IF (_p.cust_ffshipto) THEN
          -- Use Address Save function to see if the new address entered matches
          -- data for the shipto number.  If not that will insert new address for CRM
          SELECT SaveAddr(
            NULL,
            NULL,
            NEW.quhead_shiptoaddress1,
            NEW.quhead_shiptoaddress2,
            NEW.quhead_shiptoaddress3,
            NEW.quhead_shiptocity,
            NEW.quhead_shiptostate,
            NEW.quhead_shiptozipcode,
            NEW.quhead_shiptocountry,
            'CHANGEONE') INTO _addrId;
          SELECT shipto_addr_id INTO _shiptoid FROM shiptoinfo WHERE (shipto_id=NEW.quhead_shipto_id);
           -- If the address passed doesn't match shipto address, then it's something else
           IF (_shiptoid <> _addrId) THEN
             NEW.quhead_shipto_id := NULL;
           END IF;
        ELSE
          SELECT quhead_shipto_id INTO _shiptoid FROM quhead WHERE (quhead_id=NEW.quhead_id);
          -- Get the shipto address
            IF (COALESCE(NEW.quhead_shipto_id,-1) <> COALESCE(_shiptoid,-1)) THEN
            SELECT * INTO _a 
            FROM shiptoinfo
            LEFT OUTER JOIN cntct ON (shipto_cntct_id=cntct_id)
            LEFT OUTER JOIN addr ON (shipto_addr_id=addr_id)
            WHERE (shipto_id=NEW.quhead_shipto_id);
            IF (FOUND) THEN
              -- Free form not allowed so we're going to make sure address matches Shipto data
              NEW.quhead_shiptoname := COALESCE(_a.shipto_name,'');
              NEW.quhead_shiptophone := COALESCE(_a.cntct_phone,'');
              NEW.quhead_shiptoaddress1 := COALESCE(_a.addr_line1,'');
              NEW.quhead_shiptoaddress2 := COALESCE(_a.addr_line2,'');
              NEW.quhead_shiptoaddress3 := COALESCE(_a.addr_line3,'');    
              NEW.quhead_shiptocity := COALESCE(_a.addr_city,''); 
              NEW.quhead_shiptostate := COALESCE(_a.addr_state,'');
              NEW.quhead_shiptozipcode := COALESCE(_a.addr_postalcode,'');
              NEW.quhead_shiptocountry := COALESCE(_a.addr_country,''); 
            ELSE
              -- If no shipto data and free form not allowed, this won't work
              RAISE EXCEPTION 'Free form Shipto is not allowed on this Customer. You must supply a valid Shipto ID.';
            END IF;
          END IF;
        END IF;
      END IF;
    END IF;
  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='SalesOrderChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'Q', NEW.quhead_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN

        IF (OLD.quhead_terms_id <> NEW.quhead_terms_id) THEN
          PERFORM postComment( _cmnttypeid, 'Q', NEW.quhead_id,
                               ('Terms Changed from "' || oldterms.terms_code || '" to "' || newterms.terms_code || '"') )
          FROM terms AS oldterms, terms AS newterms
          WHERE ( (oldterms.terms_id=OLD.quhead_terms_id)
           AND (newterms.terms_id=NEW.quhead_terms_id) );
        END IF;

      ELSIF (TG_OP = 'DELETE') THEN
        DELETE FROM comment
        WHERE ( (comment_source='Q')
         AND (comment_source_id=OLD.quhead_id) );
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;

END;

Function: public._quitemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check NUMERIC;
BEGIN

  --If auto calculate freight, recalculate quhead_freight
  IF (SELECT quhead_calcfreight FROM quhead WHERE (quhead_id=NEW.quitem_quhead_id)) THEN
    UPDATE quhead SET quhead_freight =
      (SELECT SUM(freightdata_total) FROM freightDetail('QU',
                                                        quhead_id,
                                                        quhead_cust_id,
                                                        quhead_shipto_id,
                                                        quhead_quotedate,
                                                        quhead_shipvia,
                                                        quhead_curr_id))
    WHERE quhead_id=NEW.quitem_quhead_id;
  END IF;

  RETURN NEW;
END;

Function: public._quitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check NUMERIC;
  _itemNumber TEXT;
BEGIN
  -- Check
  IF (NEW.quitem_scheddate IS NULL) THEN
  	RAISE EXCEPTION 'A schedule date is required.';
  END IF;

  -- If this is imported, go ahead and insert default characteristics
   IF ((TG_OP = 'INSERT') AND NEW.quitem_imported) THEN
     PERFORM updateCharAssignment('SI', NEW.quitem_id, char_id, charass_value) 
     FROM (
       SELECT DISTINCT char_id, char_name, charass_value
       FROM charass, char, itemsite, item
       WHERE ((itemsite_id=NEW.quitem_itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (charass_target_type='I') 
       AND (charass_target_id=item_id)
       AND (charass_default)
       AND (char_id=charass_char_id))
       ORDER BY char_name) AS data;
   END IF;

  RETURN NEW;
END;

Function: public._quitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _check BOOLEAN;

BEGIN
  --  Checks
  SELECT checkPrivilege('MaintainQuotes') INTO _check;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Quotes.';
  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='SalesOrderChangeLog') ) THEN
--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
  ELSE
    _cmnttypeid := -1;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    IF (_cmnttypeid <> -1) THEN
      PERFORM postComment(_cmnttypeid, 'QI', NEW.quitem_id, 'Created');
    END IF;

    RETURN NEW;

  ELSE
    IF (TG_OP = 'DELETE') THEN
      DELETE FROM comment
      WHERE ( (comment_source='QI')
       AND (comment_source_id=OLD.quitem_id) );

      DELETE FROM charass
       WHERE ((charass_target_type='QI')
         AND  (charass_target_id=OLD.quitem_id));
 
      RETURN OLD;

    ELSE
      IF (TG_OP = 'UPDATE') THEN

        IF (NEW.quitem_qtyord <> OLD.quitem_qtyord) THEN
          IF (_cmnttypeid <> -1) THEN
            PERFORM postComment( _cmnttypeid, 'QI', NEW.quitem_id,
                                 ( 'Changed Qty. Ordered from ' || formatQty(OLD.quitem_qtyord) ||
                                   ' to ' || formatQty(NEW.quitem_qtyord) ) );
          END IF;

        END IF;

        IF (NEW.quitem_scheddate <> OLD.quitem_scheddate) THEN
          IF (_cmnttypeid <> -1) THEN
            PERFORM postComment( _cmnttypeid, 'QI', NEW.quitem_id,
                                 ( 'Changed Sched. Date from ' || formatDate(OLD.quitem_scheddate) ||
                                   ' to ' || formatDate(NEW.quitem_scheddate)) );
          END IF;

        END IF;

      END IF; 
    END IF;
  END IF;

--  NEW.quitem_lastupdated = CURRENT_TIMESTAMP;

  RETURN NEW;

END;

Function: public._recuraftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _parentid   INTEGER;
  _parenttype TEXT;
BEGIN
  IF (TG_OP = 'DELETE') THEN
    IF (UPPER(OLD.recur_parent_type) = 'TODO') THEN
      UPDATE todoitem SET todoitem_recurring_todoitem_id=NULL
       WHERE (todoitem_recurring_todoitem_id=OLD.recur_parent_id);
    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._reporttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  NEW.report_loaddate = CURRENT_TIMESTAMP;
  RETURN NEW;

END;

Function: public._salesrepafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

BEGIN
  IF (SELECT fetchMetricValue('DefaultSalesRep') = OLD.salesrep_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Sales Rep [xtuple: salesrep, -1, %]',
                    OLD.salesrep_number;
  END IF;

  PERFORM postComment(_cmnttypeid, 'SR', OLD.salesrep_id,
                      'Deleted "' || OLD.salesrep_number || '"');

  RETURN OLD;
END;

Function: public._salesrepaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN

  IF (TG_OP = 'INSERT') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_salesrep_id=NEW.salesrep_id,
                         crmacct_name=NEW.salesrep_name
      WHERE crmacct_number=NEW.salesrep_number;
      IF (FOUND) THEN
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,      crmacct_name,      crmacct_active,
                            crmacct_type,        crmacct_salesrep_id
                  ) VALUES (NEW.salesrep_number, NEW.salesrep_name, NEW.salesrep_active,
                            'I',                 NEW.salesrep_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    -- TODO: default characteristic assignments?

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.salesrep_number
    WHERE ((crmacct_salesrep_id=NEW.salesrep_id)
      AND  (crmacct_number!=NEW.salesrep_number));

    UPDATE crmacct SET crmacct_name = NEW.salesrep_name
    WHERE ((crmacct_salesrep_id=NEW.salesrep_id)
      AND  (crmacct_name!=NEW.salesrep_name));
  END IF;

  IF (fetchMetricBool('SalesRepChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.salesrep_active <> NEW.salesrep_active) THEN
          PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id,
                              CASE WHEN NEW.salesrep_active THEN 'Activated'
                                   ELSE 'Deactivated' END);
        END IF;

        IF (OLD.salesrep_number <> NEW.salesrep_number) THEN
          PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id,
                              'Number changed from "' || OLD.salesrep_number ||
                              '" to "' || NEW.salesrep_number || '"');
        END IF;

        IF (OLD.salesrep_name <> NEW.salesrep_name) THEN
          PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id,
                              'Name changed from "' || OLD.salesrep_name ||
                              '" to "' || NEW.salesrep_name || '"');
        END IF;

        IF (OLD.salesrep_commission <> NEW.salesrep_commission) THEN
          PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id,
                              'Commission changed from "' || OLD.salesrep_commission ||
                              '" to "' || NEW.salesrep_commission || '"');
        END IF;

        IF (OLD.salesrep_method <> NEW.salesrep_method) THEN
          PERFORM postComment(_cmnttypeid, 'SR', NEW.salesrep_id,
                              'Method changed from "' || OLD.salesrep_method ||
                              '" to "' || NEW.salesrep_method || '"');
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._salesrepbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  IF NOT (checkPrivilege('MaintainSalesReps')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Sales Reps.';
  END IF;

  IF (TG_OP IN ('INSERT', 'UPDATE')) THEN
    IF (NEW.salesrep_number IS NULL) THEN
      RAISE EXCEPTION 'You must supply a valid Sales Rep Number.';
    END IF;

    IF (NEW.salesrep_commission IS NULL) THEN
      RAISE EXCEPTION 'You must supply a Commission Rate for this Sales Rep.';
    END IF;

    IF (TG_OP = 'INSERT' AND fetchMetricText('CRMAccountNumberGeneration') IN ('A','O') AND isNumeric(NEW.salesrep_number)) THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('CRMAccountNumber', NEW.salesrep_number);
    END IF;

    NEW.salesrep_number = UPPER(NEW.salesrep_number);

    -- deprecated column salesrep_emp_id
    -- TODO: will this prevent breaking the crmacct-emp relationship?
    IF (TG_OP = 'UPDATE') THEN
      SELECT crmacct_emp_id INTO NEW.salesrep_emp_id
        FROM crmacct
       WHERE crmacct_salesrep_id = NEW.salesrep_id;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    UPDATE crmacct SET crmacct_salesrep_id = NULL
     WHERE crmacct_salesrep_id = OLD.salesrep_id;
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._shipdatasumtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  IF (LENGTH(TRIM(NEW.shipdatasum_shiphead_number)) = 0) THEN
    NEW.shipdatasum_shiphead_number = NULL;
  END IF;

  RETURN NEW;

END;

Function: public._shipdatatrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _newShipdata_cohead_number 	INTEGER;
  _shipdatasum_shipper 		TEXT;
  _rows				INTEGER;
  _cohead_id 			INTEGER;
  _shiphead_number 		TEXT;
  _headcount			INTEGER;

BEGIN
  --  This is where the shipper is identified and may need to be changed
  NEW.shipdata_cohead_number := TRIM(NEW.shipdata_cohead_number);

  IF (substring(NEW.shipdata_cosmisc_tracknum from 1 for 2) = '1Z') THEN
    _shipdatasum_shipper := 'UPS';
  ELSE
    _shipdatasum_shipper := 'UNKNOWN';
  END IF;

  IF (LENGTH(TRIM(NEW.shipdata_shiphead_number)) = 0) THEN
    NEW.shipdata_shiphead_number := NULL;
  END IF;

  IF (NEW.shipdata_cosmisc_tracknum = NEW.shipdata_cosmisc_packnum_tracknum) THEN
    IF (NEW.shipdata_void_ind = 'Y') THEN
      --  Delete the current shipdatasum
      DELETE FROM shipdatasum
      WHERE ((shipdatasum_cohead_number = NEW.shipdata_cohead_number)
	AND  (shipdatasum_cosmisc_tracknum = NEW.shipdata_cosmisc_tracknum));

    ELSIF (TG_OP = 'INSERT') THEN

--      RAISE NOTICE 'Getting cohead_id (%)', NEW.shipdata_cohead_number;
      IF (NEW.shipdata_shiphead_number IS NULL) THEN
        SELECT cohead_id INTO _cohead_id FROM cohead WHERE cohead_number = NEW.shipdata_cohead_number;

        IF (FOUND) THEN

--          RAISE NOTICE 'Getting shiphead number (%)', _cohead_id;
          SELECT count(shiphead_order_id), MAX(shiphead_number) INTO _headcount, _shiphead_number 
          FROM shiphead 
          WHERE ((shiphead_tracknum IS NULL OR shiphead_tracknum = '') 
          AND ( shiphead_order_type = 'SO' and shiphead_order_id = _cohead_id) );
          
          IF (_headcount = 1) THEN
--            RAISE NOTICE 'Updating Shiphead Number (%)', _shiphead_number;
            NEW.shipdata_shiphead_number = _shiphead_number;
            
          ELSIF (_headcount > 1) THEN
            -- Trap for potential workflow problem.  Can only infer shiphead from sales order number 
            -- if shipping one at a time
            RAISE EXCEPTION 'Multiple shipments exist for this order.  Please provide a specific a shipment number.';
          END IF;
        END IF;
      END IF;

      INSERT INTO shipdatasum
	      (shipdatasum_cohead_number, shipdatasum_cosmisc_tracknum,
	       shipdatasum_cosmisc_packnum_tracknum, shipdatasum_weight,
	       shipdatasum_base_freight, shipdatasum_total_freight,
	       shipdatasum_base_freight_curr_id, shipdatasum_total_freight_curr_id,
	       shipdatasum_shipper, shipdatasum_billing_option,
	       shipdatasum_package_type, shipdatasum_shiphead_number)
       VALUES (NEW.shipdata_cohead_number, NEW.shipdata_cosmisc_tracknum,
	       NEW.shipdata_cosmisc_packnum_tracknum, NEW.shipdata_weight,
	       NEW.shipdata_base_freight, NEW.shipdata_total_freight,
	       NEW.shipdata_base_freight_curr_id, NEW.shipdata_total_freight_curr_id,
	       _shipdatasum_shipper, NEW.shipdata_billing_option,
	       NEW.shipdata_package_type, NEW.shipdata_shiphead_number);

    ELSIF (TG_OP = 'UPDATE') THEN
       UPDATE shipdatasum SET
	      shipdatasum_cohead_number=NEW.shipdata_cohead_number,
	      shipdatasum_cosmisc_tracknum=NEW.shipdata_cosmisc_tracknum,
	      shipdatasum_cosmisc_packnum_tracknum=NEW.shipdata_cosmisc_packnum_tracknum,
	      shipdatasum_weight=NEW.shipdata_weight,
	      shipdatasum_base_freight=NEW.shipdata_base_freight,
	      shipdatasum_total_freight=NEW.shipdata_total_freight,
	      shipdatasum_base_freight_curr_id=NEW.shipdata_base_freight_curr_id,
	      shipdatasum_total_freight_curr_id=NEW.shipdata_total_freight_curr_id,
	      shipdatasum_shipper=_shipdatasum_shipper,
	      shipdatasum_billing_option=NEW.shipdata_billing_option,
	      shipdatasum_package_type=NEW.shipdata_package_type,
	      shipdatasum_shiphead_number=NEW.shipdata_shiphead_number
       WHERE ((TRIM(shipdatasum_cohead_number)=TRIM(OLD.shipdata_cohead_number))
	  AND (TRIM(shipdatasum_cosmisc_tracknum)=TRIM(OLD.shipdata_cosmisc_tracknum))
	  AND (TRIM(shipdatasum_cosmisc_packnum_tracknum)=TRIM(OLD.shipdata_cosmisc_packnum_tracknum)));

       GET DIAGNOSTICS _rows = ROW_COUNT;
       IF (_rows <= 0) THEN
	 INSERT INTO shipdatasum
		(shipdatasum_cohead_number, shipdatasum_cosmisc_tracknum,
		 shipdatasum_cosmisc_packnum_tracknum, shipdatasum_weight,
		 shipdatasum_base_freight, shipdatasum_total_freight,
		 shipdatasum_base_freight_curr_id, shipdatasum_total_freight_curr_id,
		 shipdatasum_shipper, shipdatasum_billing_option,
		 shipdatasum_package_type, shipdatasum_shiphead_number)
	 VALUES (NEW.shipdata_cohead_number, NEW.shipdata_cosmisc_tracknum,
		 NEW.shipdata_cosmisc_packnum_tracknum, NEW.shipdata_weight,
		 NEW.shipdata_base_freight, NEW.shipdata_total_freight,
		 NEW.shipdata_base_freight_curr_id, NEW.shipdata_total_freight_curr_id,
		 _shipdatasum_shipper, NEW.shipdata_billing_option,
		 NEW.shipdata_package_type, NEW.shipdata_shiphead_number);
       END IF;
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._shipformafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (fetchMetricValue('DefaultShipFormId') = OLD.shipform_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Shipping Form [xtuple: shipform, -1, %, %]',
                    OLD.shipform_name, OLD.shipform_report_name;
  END IF;

  RETURN OLD;
END;

Function: public._shipheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF ((TG_OP = 'INSERT') OR (TG_OP = 'UPDATE')) THEN

    IF (NEW.shiphead_order_type = 'SO'
	AND NEW.shiphead_order_id   IN (SELECT cohead_id FROM cohead)) THEN
      RETURN NEW;

    ELSEIF (NEW.shiphead_order_type = 'TO'
	AND NEW.shiphead_order_id   IN (SELECT tohead_id FROM tohead)) THEN
      RETURN NEW;

    END IF;

    RAISE EXCEPTION '% with id % does not exist',
		    NEW.shiphead_order_type, NEW.shiphead_order_id;
    RETURN OLD;

  END IF;

  RETURN NEW;
END;

Function: public._shiptoinfoaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN
  IF (NEW.shipto_default) THEN
    UPDATE shiptoinfo
    SET shipto_default = false
    WHERE ((shipto_cust_id=NEW.shipto_cust_id)
    AND (shipto_id <> NEW.shipto_id));
  END IF;

  IF (SELECT fetchMetricBool('CustomerChangeLog')) THEN
--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'C', NEW.shipto_cust_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.shipto_name <> NEW.shipto_name) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.shipto_cust_id,
                               ( NEW.shipto_name || ': Ship To Name Changed from "' || COALESCE(OLD.shipto_name, '') ||
                                 '" to "' || COALESCE(NEW.shipto_name, '') || '"' ) );
        END IF;
        IF (OLD.shipto_shipvia <> NEW.shipto_shipvia) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.shipto_cust_id,
                               ( NEW.shipto_name || ': Ship To ShipVia Changed from "' || COALESCE(OLD.shipto_shipvia, '') ||
                                 '" to "' || COALESCE(NEW.shipto_shipvia, '') || '"' ) );
        END IF;
        IF (COALESCE(OLD.shipto_taxzone_id, -1) <> COALESCE(NEW.shipto_taxzone_id, -1)) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.shipto_cust_id,
                               ( NEW.shipto_name || ': Ship To Tax Zone Changed from "' || COALESCE((SELECT taxzone_code
                                                                                            FROM taxzone
                                                                                            WHERE taxzone_id=OLD.shipto_taxzone_id), 'None') ||
                                 '" to "' || COALESCE((SELECT taxzone_code
                                              FROM taxzone
                                              WHERE taxzone_id=NEW.shipto_taxzone_id), 'None') || '"' ) );
        END IF;
        IF (OLD.shipto_shipzone_id <> NEW.shipto_shipzone_id) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.shipto_cust_id,
                               ( NEW.shipto_name || ': Ship To Shipping Zone Changed from "' || (SELECT shipzone_name
                                                                                                 FROM shipzone
                                                                                                 WHERE shipzone_id=OLD.shipto_shipzone_id) ||
                                 '" to "' || (SELECT shipzone_name
                                              FROM shipzone
                                              WHERE shipzone_id=NEW.shipto_shipzone_id) || '"' ) );
        END IF;
        IF (OLD.shipto_salesrep_id <> NEW.shipto_salesrep_id) THEN
          PERFORM postComment( _cmnttypeid, 'C', NEW.shipto_cust_id,
                               ( NEW.shipto_name || ': Ship To Sales Rep Changed from "' || (SELECT salesrep_name
                                                                                             FROM salesrep
                                                                                             WHERE salesrep_id=OLD.shipto_salesrep_id) ||
                                 '" to "' || (SELECT salesrep_name
                                              FROM salesrep
                                              WHERE salesrep_id=NEW.shipto_salesrep_id) || '"' ) );
        END IF;
        IF (OLD.shipto_active <> NEW.shipto_active) THEN
          IF (NEW.shipto_active) THEN
            PERFORM postComment(_cmnttypeid, 'C', NEW.shipto_cust_id, (NEW.shipto_name || ': Ship To Activated'));
          ELSE
            PERFORM postComment(_cmnttypeid, 'C', NEW.shipto_cust_id, (NEW.shipto_name || ': Ship To Deactivated'));
          END IF;
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._shipviaafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (SELECT fetchMetricValue('DefaultShipViaId') = OLD.shipvia_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Ship-Via [xtuple: shipvia, -1, %]',
                    OLD.shipvia_code;
  END IF;

  RETURN OLD;
END;

Function: public._sltransaltertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _externalCompany      BOOLEAN := false;
  _updated BOOLEAN := false;
BEGIN
  IF(TG_OP='DELETE') THEN
    RAISE EXCEPTION 'You may not delete Journal Transactions once they have been created.';
  ELSIF (TG_OP = 'UPDATE') THEN	
    IF(OLD.sltrans_id != NEW.sltrans_id) THEN
      _updated := true;
    ELSIF(OLD.sltrans_date != NEW.sltrans_date) THEN
      _updated := true;
    ELSIF(OLD.sltrans_accnt_id != NEW.sltrans_accnt_id) THEN
      _updated := true;
    ELSIF(OLD.sltrans_amount != NEW.sltrans_amount) THEN
      _updated := true;
    ELSIF(OLD.sltrans_username != NEW.sltrans_username) THEN
      _updated := true;
    ELSIF( (OLD.sltrans_sequence IS NULL     AND NEW.sltrans_sequence IS NOT NULL)
        OR (OLD.sltrans_sequence IS NOT NULL AND NEW.sltrans_sequence IS NULL)
        OR (COALESCE(OLD.sltrans_sequence,0) != COALESCE(NEW.sltrans_sequence,0)) ) THEN
      _updated := true;
    ELSIF( (OLD.sltrans_created IS NULL     AND NEW.sltrans_created IS NOT NULL)
        OR (OLD.sltrans_created IS NOT NULL AND NEW.sltrans_created IS NULL)
        OR (COALESCE(OLD.sltrans_created,now()) != COALESCE(NEW.sltrans_created,now())) ) THEN
      _updated := true;
    ELSIF( (OLD.sltrans_source IS NULL     AND NEW.sltrans_source IS NOT NULL)
        OR (OLD.sltrans_source IS NOT NULL AND NEW.sltrans_source IS NULL)
        OR (COALESCE(OLD.sltrans_source,'') != COALESCE(NEW.sltrans_source,'')) ) THEN
      _updated := true;
    ELSIF( (OLD.sltrans_docnumber IS NULL     AND NEW.sltrans_docnumber IS NOT NULL)
        OR (OLD.sltrans_docnumber IS NOT NULL AND NEW.sltrans_docnumber IS NULL)
        OR (COALESCE(OLD.sltrans_docnumber,'') != COALESCE(NEW.sltrans_docnumber,'')) ) THEN
      _updated := true;
    ELSIF( (OLD.sltrans_doctype IS NULL     AND NEW.sltrans_doctype IS NOT NULL)
        OR (OLD.sltrans_doctype IS NOT NULL AND NEW.sltrans_doctype IS NULL)
        OR (COALESCE(OLD.sltrans_doctype,'') != COALESCE(NEW.sltrans_doctype,'')) ) THEN
      _updated := true;
    END IF;

    IF(_updated) THEN
      RAISE EXCEPTION 'You may not alter some Journal Transaction fields once they have been created.';
    END IF;
  ELSE
    RAISE EXCEPTION 'trigger for sltrans table called in unexpected state.';
  END IF;
  RETURN NEW;
END;

Function: public._sltransinserttrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _reqNotes BOOLEAN;
  _externalCompany      BOOLEAN := false;
BEGIN
  -- Checks
  SELECT company_external INTO _externalCompany
  FROM company JOIN accnt ON (company_number=accnt_company)
  WHERE (accnt_id=NEW.sltrans_accnt_id);
  IF (_externalCompany) THEN
    RAISE EXCEPTION 'Transactions are not allowed for G/L Accounts with External Company segments.';
  END IF;
  
  RETURN NEW;
END;

Function: public._soheadtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _p RECORD;
  _a RECORD;
  _w RECORD;
  _shiptoId INTEGER;
  _addrId INTEGER;
  _prjId INTEGER;
  _check BOOLEAN;
  _numGen CHAR(1);

BEGIN

  -- Checks
  -- Start with privileges
  IF (TG_OP = 'INSERT') THEN
    IF ( (NOT checkPrivilege('MaintainSalesOrders')) AND
       (NOT checkPrivilege('EnterReceipts')) ) THEN
      RAISE EXCEPTION 'You do not have privileges to create a Sales Order.';
    END IF;
  ELSIF (TG_OP = 'UPDATE') THEN
    IF ( (NOT checkPrivilege('MaintainSalesOrders')) AND
         (NOT checkPrivilege('IssueStockToShipping')) AND
         (NEW.cohead_holdtype = OLD.cohead_holdtype) ) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Sales Order.';
    END IF;
  ELSE
    IF ( (NOT checkPrivilege('MaintainSalesOrders')) AND
         (NOT checkPrivilege('IssueStockToShipping')) ) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Sales Order.';
    END IF;
  END IF;

  -- If this is imported, check the order number
  IF (TG_OP = 'INSERT') THEN
    IF (NEW.cohead_imported) THEN
      SELECT fetchMetricText('CONumberGeneration') INTO _numGen;
      IF ((NEW.cohead_number IS NULL) AND (_numGen='M')) THEN
        RAISE EXCEPTION 'You must supply an Order Number.';
      ELSE
        IF (NEW.cohead_number IS NULL) THEN
          SELECT fetchsonumber() INTO NEW.cohead_number;
        END IF;
      END IF;
    END IF;

    IF (fetchMetricText('CONumberGeneration') IN ('A','O')) THEN
      --- clear the number from the issue cache
      PERFORM clearNumberIssue('SoNumber', NEW.cohead_number);
    END IF;
  ELSE
    IF (TG_OP = 'UPDATE') THEN
      IF (NEW.cohead_number <> OLD.cohead_number) THEN
        RAISE EXCEPTION 'The order number may not be changed.';
      END IF;
    END IF;
  END IF;

  IF (TG_OP IN ('INSERT','UPDATE')) THEN

    -- Get Customer data
    IF (NEW.cohead_shipto_id IS NULL) THEN
      SELECT cust_creditstatus,cust_number,cust_usespos,cust_blanketpos,cust_ffbillto,
	     cust_ffshipto,cust_name,cust_salesrep_id,cust_terms_id,cust_shipvia,
	     cust_shipchrg_id,cust_shipform_id,cust_commprcnt,cust_curr_id,cust_taxzone_id,
  	     cntct.*,addr.*,
	     shipto_id,shipto_addr_id,shipto_name,shipto_salesrep_id,shipto_shipvia,
	     shipto_shipchrg_id,shipto_shipform_id,shipto_commission,shipto_taxzone_id INTO _p
      FROM custinfo
        LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
        LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
        LEFT OUTER JOIN shiptoinfo ON ((cust_id=shipto_cust_id) AND shipto_default)
      WHERE (cust_id=NEW.cohead_cust_id);
    ELSE
      SELECT cust_creditstatus,cust_number,cust_usespos,cust_blanketpos,cust_ffbillto,
	     cust_ffshipto,cust_name,cust_salesrep_id,cust_terms_id,cust_shipvia,
	     cust_shipchrg_id,cust_shipform_id,cust_commprcnt,cust_curr_id,cust_taxzone_id,
  	     cntct.*,addr.*,
	     shipto_id,shipto_addr_id,shipto_name,shipto_salesrep_id,shipto_shipvia,
	     shipto_shipchrg_id,shipto_shipform_id,shipto_commission,shipto_taxzone_id INTO _p
      FROM shiptoinfo,custinfo
        LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
        LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
      WHERE ((cust_id=NEW.cohead_cust_id)
        AND  (shipto_id=NEW.cohead_shipto_id));
    END IF;

    -- If there is customer data, then we can get to work
    IF (FOUND) THEN

      -- Check Credit
      IF (TG_OP = 'INSERT') THEN
          IF (_p.cust_creditstatus = 'H') THEN
            SELECT checkPrivilege('CreateSOForHoldCustomer') INTO _check;
            IF NOT (_check) THEN
              RAISE EXCEPTION 'Customer % has been placed 
                               on a Credit Hold and you do not have 
                               privilege to create Sales Orders for 
                               Customers on Credit Hold.  The selected 
                               Customer must be taken off of Credit Hold 
                               before you may create a new Sales Order 
                               for the Customer.',_p.cust_number;
            ELSE
              NEW.cohead_holdtype='C';
            END IF;
          END IF;
          IF (_p.cust_creditstatus = 'W') THEN
            SELECT checkPrivilege('CreateSOForWarnCustomer') INTO _check;
            IF NOT (_check) THEN
              RAISE EXCEPTION 'Customer % has been placed on 
                              a Credit Warning and you do not have 
                              privilege to create Sales Orders for 
                              Customers on Credit Warning.  The 
                              selected Customer must be taken off of 
                              Credit Warning before you may create a 
                              new Sales Order for the Customer.',_p.cust_number;
            ELSE
              NEW.cohead_holdtype='C';
            END IF;
          END IF;

          -- Set to defaults if values not provided
          NEW.cohead_shipto_id 	:= COALESCE(NEW.cohead_shipto_id,_p.shipto_id);
          NEW.cohead_terms_id		:= COALESCE(NEW.cohead_terms_id,_p.cust_terms_id);
          NEW.cohead_orderdate		:= COALESCE(NEW.cohead_orderdate,current_date);
          NEW.cohead_packdate		:= COALESCE(NEW.cohead_packdate,NEW.cohead_orderdate);
          NEW.cohead_curr_id		:= COALESCE(NEW.cohead_curr_id,_p.cust_curr_id,basecurrid());
          NEW.cohead_freight		:= COALESCE(NEW.cohead_freight,0);
          NEW.cohead_custponumber	:= COALESCE(NEW.cohead_custponumber,'');
          NEW.cohead_ordercomments	:= COALESCE(NEW.cohead_ordercomments,'');
          NEW.cohead_shipcomments	:= COALESCE(NEW.cohead_shipcomments,'');
          NEW.cohead_shiptophone	:= COALESCE(NEW.cohead_shiptophone,'');
          NEW.cohead_misc		:= COALESCE(NEW.cohead_misc,0);
          NEW.cohead_misc_descrip	:= COALESCE(NEW.cohead_misc_descrip,'');
          NEW.cohead_shipcomplete	:= COALESCE(NEW.cohead_shipcomplete,false);

          IF (_p.shipto_id IS NOT NULL) THEN -- Pull in over ride values
	    NEW.cohead_salesrep_id 	:= COALESCE(NEW.cohead_salesrep_id,_p.shipto_salesrep_id);
	    NEW.cohead_shipvia		:= COALESCE(NEW.cohead_shipvia,_p.shipto_shipvia);
	    NEW.cohead_shipchrg_id	:= COALESCE(NEW.cohead_shipchrg_id,_p.shipto_shipchrg_id);
	    NEW.cohead_shipform_id	:= COALESCE(NEW.cohead_shipform_id,_p.shipto_shipform_id);
	    NEW.cohead_commission	:= COALESCE(NEW.cohead_commission,_p.shipto_commission);
	    IF (NEW.cohead_taxzone_id=-1) THEN
	      NEW.cohead_taxzone_id 	:= NULL;
	    ELSE
	      NEW.cohead_taxzone_id	:= COALESCE(NEW.cohead_taxzone_id,_p.shipto_taxzone_id);
	    END IF;
	  ELSE
	    NEW.cohead_salesrep_id 	:= COALESCE(NEW.cohead_salesrep_id,_p.cust_salesrep_id);
	    NEW.cohead_shipvia		:= COALESCE(NEW.cohead_shipvia,_p.cust_shipvia);
	    NEW.cohead_shipchrg_id	:= COALESCE(NEW.cohead_shipchrg_id,_p.cust_shipchrg_id);
	    NEW.cohead_shipform_id	:= COALESCE(NEW.cohead_shipform_id,_p.cust_shipform_id);
	    NEW.cohead_commission	:= COALESCE(NEW.cohead_commission,_p.cust_commprcnt);
	    IF (NEW.cohead_taxzone_id=-1) THEN
	      NEW.cohead_taxzone_id 	:= NULL;
	    ELSE
	      NEW.cohead_taxzone_id	:= COALESCE(NEW.cohead_taxzone_id,_p.cust_taxzone_id);
	    END IF;
          END IF;

          IF ((NEW.cohead_warehous_id IS NULL) OR (NEW.cohead_fob IS NULL)) THEN
            IF (NEW.cohead_warehous_id IS NULL) THEN
              SELECT warehous_id,warehous_fob INTO _w
              FROM usrpref, whsinfo
              WHERE ((warehous_id=CAST(usrpref_value AS INTEGER))
                AND (warehous_shipping)
                AND (warehous_active)
                AND (usrpref_username=getEffectiveXtUser())
                AND (usrpref_name='PreferredWarehouse'));
            ELSE
              SELECT warehous_id,warehous_fob INTO _w
              FROM whsinfo
              WHERE (warehous_id=NEW.cohead_warehous_id);
            END IF;
            
            IF (FOUND) THEN
              NEW.cohead_warehous_id 	:= COALESCE(NEW.cohead_warehous_id,_w.warehous_id);
              NEW.cohead_fob		:= COALESCE(NEW.cohead_fob,_w.warehous_fob);
            END IF;
          END IF;
          
      END IF;

      -- Only Check P/O logic for imports, because UI checks when entire order is saved
      IF (NEW.cohead_imported) THEN

        -- Check for required Purchase Order
        IF (_p.cust_usespos AND ((NEW.cohead_custponumber IS NULL) OR (TRIM(BOTH FROM NEW.cohead_custponumber)=''))) THEN
            RAISE EXCEPTION 'You must enter a Customer P/O for this Sales Order.';
        END IF;
 
        -- Check for duplicate Purchase Orders if not allowed
        IF (_p.cust_usespos AND NOT (_p.cust_blanketpos)) THEN
          SELECT cohead_id INTO _a
          FROM cohead
          WHERE ((cohead_cust_id=NEW.cohead_cust_id)
          AND  (cohead_id<>NEW.cohead_id)
          AND  (UPPER(cohead_custponumber) = UPPER(NEW.cohead_custponumber)) )
          UNION
          SELECT quhead_id
          FROM quhead
          WHERE ((quhead_cust_id=NEW.cohead_cust_id)
          AND  (quhead_id<>NEW.cohead_id)
          AND  (UPPER(quhead_custponumber) = UPPER(NEW.cohead_custponumber)) );
          IF (FOUND) THEN
	    RAISE EXCEPTION 'This Customer does not use Blanket P/O
                            Numbers and the P/O Number you entered has 
                            already been used for another Sales Order.
                            Please verify the P/O Number and either
                            enter a new P/O Number or add to the
                            existing Sales Order.';
         END IF;
        END IF;
      END IF;

      --Auto create project if applicable
      IF ((TG_OP = 'INSERT') AND (NEW.cohead_prj_id IS NULL)) THEN
        SELECT fetchMetricBool('AutoCreateProjectsForOrders') INTO _check;
        IF (_check) THEN
          SELECT NEXTVAL('prj_prj_id_seq') INTO _prjId;
          NEW.cohead_prj_id := _prjId;
          INSERT INTO prj (prj_id, prj_number, prj_name, prj_descrip, prj_status, prj_so, prj_wo, prj_po)
               VALUES(_prjId, NEW.cohead_number, NEW.cohead_number, 'Auto Generated Project from Sales Order.', 'O', TRUE, TRUE, TRUE);
        END IF;
      END IF;

      IF (TG_OP = 'UPDATE') THEN
        SELECT true INTO _check
        FROM coitem
        WHERE ( (coitem_status='C')
        AND (coitem_cohead_id=NEW.cohead_id) ) 
        LIMIT 1;

        IF (NOT FOUND) THEN

        --Update project references on supply
        UPDATE pr SET pr_prj_id=NEW.cohead_prj_id
                   FROM coitem
                   WHERE ((coitem_cohead_id=NEW.cohead_id) 
                   AND  (coitem_order_type='R') 
                   AND  (coitem_order_id=pr_id));

        PERFORM changeWoProject(coitem_order_id, NEW.cohead_prj_id, TRUE)
                    FROM coitem
                    WHERE ((coitem_cohead_id=NEW.cohead_id)
                    AND  (coitem_order_type='W'));
        ELSE
          IF NEW.cohead_prj_id <> COALESCE(OLD.cohead_prj_id,-1) THEN
            RAISE EXCEPTION 'You can not change the project ID on orders with closed lines.';
          END IF;
        END IF;
      END IF;

      -- Deal with Billing Address
      IF (TG_OP = 'INSERT') THEN
        IF (_p.cust_ffbillto) THEN
          -- If they didn't supply data, we'll put in the bill to contact and address
          NEW.cohead_billto_cntct_id=COALESCE(NEW.cohead_billto_cntct_id,_p.cntct_id);
          NEW.cohead_billto_cntct_honorific=COALESCE(NEW.cohead_billto_cntct_honorific,_p.cntct_honorific,'');
          NEW.cohead_billto_cntct_first_name=COALESCE(NEW.cohead_billto_cntct_first_name,_p.cntct_first_name,'');
          NEW.cohead_billto_cntct_middle=COALESCE(NEW.cohead_billto_cntct_middle,_p.cntct_middle,'');    
          NEW.cohead_billto_cntct_last_name=COALESCE(NEW.cohead_billto_cntct_last_name,_p.cntct_last_name,''); 
          NEW.cohead_billto_cntct_phone=COALESCE(NEW.cohead_billto_cntct_phone,_p.cntct_phone,'');
          NEW.cohead_billto_cntct_title=COALESCE(NEW.cohead_billto_cntct_title,_p.cntct_title,'');
          NEW.cohead_billto_cntct_fax=COALESCE(NEW.cohead_billto_cntct_fax,_p.cntct_fax,''); 
          NEW.cohead_billto_cntct_email=COALESCE(NEW.cohead_billto_cntct_email,_p.cntct_email,''); 
          NEW.cohead_billtoname=COALESCE(NEW.cohead_billtoname,_p.cust_name,'');
          NEW.cohead_billtoaddress1=COALESCE(NEW.cohead_billtoaddress1,_p.addr_line1,'');
          NEW.cohead_billtoaddress2=COALESCE(NEW.cohead_billtoaddress2,_p.addr_line2,'');
          NEW.cohead_billtoaddress3=COALESCE(NEW.cohead_billtoaddress3,_p.addr_line3,'');    
          NEW.cohead_billtocity=COALESCE(NEW.cohead_billtocity,_p.addr_city,''); 
          NEW.cohead_billtostate=COALESCE(NEW.cohead_billtostate,_p.addr_state,'');
          NEW.cohead_billtozipcode=COALESCE(NEW.cohead_billtozipcode,_p.addr_postalcode,'');
          NEW.cohead_billtocountry=COALESCE(NEW.cohead_billtocountry,_p.addr_country,'');   
        ELSE
          -- Free form not allowed, we're going to put in the address regardless
          NEW.cohead_billto_cntct_id=_p.cntct_id;
          NEW.cohead_billto_cntct_honorific=COALESCE(_p.cntct_honorific,'');
          NEW.cohead_billto_cntct_first_name=COALESCE(_p.cntct_first_name,'');
          NEW.cohead_billto_cntct_middle=COALESCE(_p.cntct_middle,'');    
          NEW.cohead_billto_cntct_last_name=COALESCE(_p.cntct_last_name,''); 
          NEW.cohead_billto_cntct_phone=COALESCE(_p.cntct_phone,'');
          NEW.cohead_billto_cntct_title=COALESCE(_p.cntct_title,'');
          NEW.cohead_billto_cntct_fax=COALESCE(_p.cntct_fax,''); 
          NEW.cohead_billto_cntct_email=COALESCE(_p.cntct_email,''); 
          NEW.cohead_billtoname=COALESCE(_p.cust_name,'');
          NEW.cohead_billtoaddress1=COALESCE(_p.addr_line1,'');
          NEW.cohead_billtoaddress2=COALESCE(_p.addr_line2,'');
          NEW.cohead_billtoaddress3=COALESCE(_p.addr_line3,'');    
          NEW.cohead_billtocity=COALESCE(_p.addr_city,''); 
          NEW.cohead_billtostate=COALESCE(_p.addr_state,'');
          NEW.cohead_billtozipcode=COALESCE(_p.addr_postalcode,'');
          NEW.cohead_billtocountry=COALESCE(_p.addr_country,'');
        END IF;
      END IF;

      -- Now let's look at Shipto Address
      -- If there's nothing in the address fields and there is a shipto id 
      -- or there is a default address available, let's put in some shipto address data
      IF ((TG_OP = 'INSERT') 
        AND NOT ((NEW.cohead_shipto_id IS NULL) AND NOT _p.cust_ffshipto)
        AND (NEW.cohead_shipto_cntct_id IS NULL)
        AND (NEW.cohead_shipto_cntct_honorific IS NULL)
        AND (NEW.cohead_shipto_cntct_first_name IS NULL)
        AND (NEW.cohead_shipto_cntct_middle IS NULL)
        AND (NEW.cohead_shipto_cntct_last_name IS NULL)
        AND (NEW.cohead_shipto_cntct_suffix IS NULL)
        AND (NEW.cohead_shipto_cntct_phone IS NULL)
        AND (NEW.cohead_shipto_cntct_title IS NULL)
        AND (NEW.cohead_shipto_cntct_fax IS NULL)
        AND (NEW.cohead_shipto_cntct_email IS NULL)
        AND (NEW.cohead_shiptoname IS NULL)
        AND (NEW.cohead_shiptoaddress1 IS NULL)
        AND (NEW.cohead_shiptoaddress2 IS NULL)
        AND (NEW.cohead_shiptoaddress3 IS NULL)
        AND (NEW.cohead_shiptocity IS NULL)
        AND (NEW.cohead_shiptostate IS NULL)
        AND (NEW.cohead_shiptocountry IS NULL)) THEN
        IF ((NEW.cohead_shipto_id IS NULL) AND (_p.shipto_id IS NOT NULL)) THEN
          _shiptoId := _p.shipto_addr_id;
        ELSE
          _shiptoId := NEW.cohead_shipto_id;
        END IF;

        SELECT * INTO _a 
        FROM shiptoinfo
          LEFT OUTER JOIN addr ON (addr_id=shipto_addr_id)
          LEFT OUTER JOIN cntct ON (cntct_id=shipto_cntct_id)
        WHERE (shipto_id=_shiptoId);

        NEW.cohead_shipto_cntct_id := _a.cntct_id;
        NEW.cohead_shipto_cntct_honorific := COALESCE(_a.cntct_honorific,'');
        NEW.cohead_shipto_cntct_first_name := COALESCE(_a.cntct_first_name,'');
        NEW.cohead_shipto_cntct_middle := COALESCE(_a.cntct_middle,'');
        NEW.cohead_shipto_cntct_last_name := COALESCE(_a.cntct_last_name,'');
	NEW.cohead_shipto_cntct_suffix := COALESCE(_a.cntct_suffix,'');
	NEW.cohead_shipto_cntct_phone := COALESCE(_a.cntct_phone,'');
	NEW.cohead_shipto_cntct_title := COALESCE(_a.cntct_title,'');
	NEW.cohead_shipto_cntct_fax := COALESCE(_a.cntct_fax,'');
	NEW.cohead_shipto_cntct_email := COALESCE(_a.cntct_email,'');
        NEW.cohead_shiptoname := COALESCE(_p.shipto_name,'');
        NEW.cohead_shiptoaddress1 := COALESCE(_a.addr_line1,'');
        NEW.cohead_shiptoaddress2 := COALESCE(_a.addr_line2,'');
        NEW.cohead_shiptoaddress3 := COALESCE(_a.addr_line3,'');    
        NEW.cohead_shiptocity := COALESCE(_a.addr_city,''); 
        NEW.cohead_shiptostate := COALESCE(_a.addr_state,'');
        NEW.cohead_shiptozipcode := COALESCE(_a.addr_postalcode,'');
        NEW.cohead_shiptocountry := COALESCE(_a.addr_country,'');
      ELSE
        IF (_p.cust_ffshipto) THEN
          -- Use Address Save function to see if the new address entered matches
          -- data for the shipto number.  If not that will insert new address for CRM
          SELECT SaveAddr(
            NULL,
            NULL,
            NEW.cohead_shiptoaddress1,
            NEW.cohead_shiptoaddress2,
            NEW.cohead_shiptoaddress3,
            NEW.cohead_shiptocity,
            NEW.cohead_shiptostate,
            NEW.cohead_shiptozipcode,
            NEW.cohead_shiptocountry,
            'CHANGEONE') INTO _addrId;
          SELECT shipto_addr_id INTO _shiptoid FROM shiptoinfo WHERE (shipto_id=NEW.cohead_shipto_id);
          -- If the address passed doesn't match shipto address, then it's something else
          IF (_shiptoid <> _addrId) THEN
            NEW.cohead_shipto_id := NULL;
          END IF;
        ELSE
          SELECT cohead_shipto_id INTO _shiptoid FROM cohead WHERE (cohead_id=NEW.cohead_id);
          -- Get the shipto address
          IF (COALESCE(NEW.cohead_shipto_id,-1) <> COALESCE(_shiptoid,-1)) THEN
            SELECT * INTO _a 
            FROM shiptoinfo
              LEFT OUTER JOIN cntct ON (shipto_cntct_id=cntct_id)
              LEFT OUTER JOIN addr ON (shipto_addr_id=addr_id)
            WHERE (shipto_id=NEW.cohead_shipto_id);
            IF (FOUND) THEN
              -- Free form not allowed so we're going to make sure address matches Shipto data
              NEW.cohead_shipto_cntct_id=_a.cntct_id;
              NEW.cohead_shipto_cntct_honorific=COALESCE(_a.cntct_honorific,'');
              NEW.cohead_shipto_cntct_first_name=COALESCE(_a.cntct_first_name,'');
              NEW.cohead_shipto_cntct_middle=COALESCE(_a.cntct_middle,'');    
              NEW.cohead_shipto_cntct_last_name=COALESCE(_a.cntct_last_name,''); 
              NEW.cohead_shipto_cntct_phone=COALESCE(_a.cntct_phone,'');
              NEW.cohead_shipto_cntct_title=COALESCE(_a.cntct_title,'');
              NEW.cohead_shipto_cntct_fax=COALESCE(_a.cntct_fax,''); 
              NEW.cohead_shipto_cntct_email=COALESCE(_a.cntct_email,''); 
              NEW.cohead_shiptoname := COALESCE(_a.shipto_name,'');
              NEW.cohead_shiptophone := COALESCE(_a.cntct_phone,'');
              NEW.cohead_shiptoaddress1 := COALESCE(_a.addr_line1,'');
              NEW.cohead_shiptoaddress2 := COALESCE(_a.addr_line2,'');
              NEW.cohead_shiptoaddress3 := COALESCE(_a.addr_line3,'');    
              NEW.cohead_shiptocity := COALESCE(_a.addr_city,''); 
              NEW.cohead_shiptostate := COALESCE(_a.addr_state,'');
              NEW.cohead_shiptozipcode := COALESCE(_a.addr_postalcode,'');
              NEW.cohead_shiptocountry := COALESCE(_a.addr_country,''); 
            ELSE
              -- If no shipto data and free form not allowed, this won't work
              RAISE EXCEPTION 'Free form Shipto is not allowed on this Customer. You must supply a valid Shipto ID.';
            END IF;
          END IF;
        END IF;
      END IF;
    END IF;
  END IF;

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='SalesOrderChangeLog') ) THEN

    IF (TG_OP = 'INSERT') THEN
      PERFORM postComment('ChangeLog', 'S', NEW.cohead_id, 'Created');

    ELSIF (TG_OP = 'UPDATE') THEN

      IF (OLD.cohead_terms_id <> NEW.cohead_terms_id) THEN
        PERFORM postComment( 'ChangeLog', 'S', NEW.cohead_id,
                             ('Terms Changed from "' || oldterms.terms_code || '" to "' || newterms.terms_code || '"') )
        FROM terms AS oldterms, terms AS newterms
        WHERE ( (oldterms.terms_id=OLD.cohead_terms_id)
         AND (newterms.terms_id=NEW.cohead_terms_id) );
      END IF;

      IF (OLD.cohead_shipvia <> NEW.cohead_shipvia) THEN
        PERFORM postComment ('ChangeLog', 'S', New.cohead_id, ('Shipvia Changed from "' || OLD.cohead_shipvia || '" to "' || NEW.cohead_shipvia || '"'));
      END IF;

      IF (OLD.cohead_holdtype <> NEW.cohead_holdtype) THEN
        PERFORM postComment( 'ChangeLog', 'S', NEW.cohead_id,
                             ( 'Hold Type Changed from ' || (CASE OLD.cohead_holdtype WHEN('N') THEN 'No Hold'
                                                                                      WHEN('C') THEN 'Credit Hold'
                                                                                      WHEN('P') THEN 'Packing Hold'
                                                                                      WHEN('S') THEN 'Shipping Hold'
                                                                                      ELSE 'Unknown/Error' END) ||
                               ' to ' || (CASE NEW.cohead_holdtype WHEN('N') THEN 'No Hold'
                                                                   WHEN('C') THEN 'Credit Hold'
                                                                   WHEN('P') THEN 'Packing Hold'
                                                                   WHEN('S') THEN 'Shipping Hold'
                                                                   ELSE 'Unknown/Error' END) ) );
      END IF;

    ELSIF (TG_OP = 'DELETE') THEN
      DELETE FROM comment
      WHERE ( (comment_source='S')
       AND (comment_source_id=OLD.cohead_id) );
    END IF;
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    IF ( (NOT (OLD.cohead_holdtype = 'N')) AND
         (NEW.cohead_holdtype='N') ) THEN
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                            evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
             'S', NEW.cohead_id, NEW.cohead_warehous_id, NEW.cohead_number::TEXT
      FROM evntnot, evnttype
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=NEW.cohead_warehous_id)
       AND (evnttype_name='SoReleased') );
    END IF;

    IF (OLD.cohead_ordercomments <> NEW.cohead_ordercomments) THEN
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                            evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
             'S', NEW.cohead_id, NEW.cohead_warehous_id, NEW.cohead_number::TEXT
      FROM evntnot, evnttype
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=NEW.cohead_warehous_id)
       AND (evnttype_name='SoNotesChanged') );
    END IF;

    IF ((OLD.cohead_shipchrg_id != NEW.cohead_shipchrg_id)
        OR (OLD.cohead_freight != NEW.cohead_freight)
        OR (OLD.cohead_shipvia != NEW.cohead_shipvia)) THEN
      UPDATE shiphead SET 
        shiphead_shipchrg_id=NEW.cohead_shipchrg_id,
        shiphead_freight=NEW.cohead_freight,
        shiphead_shipvia=NEW.cohead_shipvia
      WHERE ((shiphead_order_type='SO')
      AND  (shiphead_order_id=NEW.cohead_id)
      AND  (NOT shiphead_shipped));
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    NEW.cohead_lastupdated = CURRENT_TIMESTAMP;

    RETURN NEW;
  END IF;

END;

Function: public._soheadtriggerafter()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (COALESCE(NEW.cohead_taxzone_id,-1) <> COALESCE(OLD.cohead_taxzone_id,-1)) THEN
    UPDATE coitem SET coitem_taxtype_id=getItemTaxType(itemsite_item_id,NEW.cohead_taxzone_id)
    FROM itemsite 
    WHERE ((itemsite_id=coitem_itemsite_id)
     AND (coitem_cohead_id=NEW.cohead_id));
  END IF;

  -- update comments on any associated drop ship POs
  IF (COALESCE(NEW.cohead_shipcomments, TEXT('')) <> COALESCE(OLD.cohead_shipcomments, TEXT(''))) THEN
    UPDATE pohead SET pohead_comments=NEW.cohead_shipcomments
    FROM poitem JOIN coitem ON (coitem_cohead_id=NEW.cohead_id AND coitem_order_type='P' AND coitem_order_id=poitem_id)
    WHERE (pohead_id=poitem_pohead_id);
  END IF;

  RETURN NEW;
END;

Function: public._soitemafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  IF (OLD.coitem_status = 'O') THEN
    IF ( (SELECT (count(*) < 1)
            FROM coitem
           WHERE ((coitem_cohead_id=OLD.coitem_cohead_id)
             AND  (coitem_id != OLD.coitem_id)
             AND  (coitem_status = 'O')) ) ) THEN
      UPDATE cohead SET cohead_status = 'C'
       WHERE ((cohead_id=OLD.coitem_cohead_id)
         AND  (cohead_status='O'));
    END IF;
  END IF;

  RETURN OLD;
END;

Function: public._soitemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check NUMERIC;
  _r RECORD;
  _po BOOLEAN;
  _kit BOOLEAN;
  _fractional BOOLEAN;
  _purchase BOOLEAN;
  _rec RECORD;
  _kstat TEXT;
  _pstat TEXT;
  _result INTEGER;
  _coitemid INTEGER;
  _itemsrcid INTEGER;
  _orderid INTEGER;

BEGIN

  _rec := NEW;

  --Cache some information
  SELECT * INTO _r
  FROM cohead
  WHERE (cohead_id=_rec.coitem_cohead_id);

  --Determine if this is a kit for later processing
  SELECT COALESCE(item_type,'')='K', item_fractional
    INTO _kit, _fractional
    FROM itemsite, item
   WHERE((itemsite_item_id=item_id)
     AND (itemsite_id=_rec.coitem_itemsite_id));
  _kit := COALESCE(_kit, false);
  _fractional := COALESCE(_fractional, false);

 --Select purchase items
  SELECT COALESCE(item_type,'')='P'
    INTO _purchase
    FROM itemsite JOIN item ON (itemsite_item_id=item_id)
   WHERE (itemsite_id=_rec.coitem_itemsite_id);
  _purchase := COALESCE(_purchase, false);
 
 --Select salesorder related to purchaseorder 
  SELECT itemsite_createsopo INTO _po 
  FROM itemsite JOIN coitem ON  (itemsite_id=coitem_itemsite_id) 
  WHERE (coitem_id=_rec.coitem_id);

  IF (_kit) THEN
  -- Kit Processing
    IF (TG_OP = 'INSERT') THEN
  -- Create Sub Lines for Kit Components
      PERFORM explodeKit(NEW.coitem_cohead_id, NEW.coitem_linenumber, 0, NEW.coitem_itemsite_id,
                         NEW.coitem_qtyord, NEW.coitem_scheddate, NEW.coitem_promdate, NEW.coitem_memo);
      IF (fetchMetricBool('KitComponentInheritCOS')) THEN
  -- Update kit line item COS
        UPDATE coitem
        SET coitem_cos_accnt_id = CASE WHEN (COALESCE(NEW.coitem_cos_accnt_id, -1) != -1)
                                         THEN NEW.coitem_cos_accnt_id
                                       WHEN (NEW.coitem_warranty)
                                         THEN resolveCOWAccount(NEW.coitem_itemsite_id, _r.cohead_cust_id, _r.cohead_saletype_id, _r.cohead_shipzone_id)
                                       ELSE resolveCOSAccount(NEW.coitem_itemsite_id, _r.cohead_cust_id, _r.cohead_saletype_id, _r.cohead_shipzone_id)
                                  END
        WHERE((coitem_cohead_id=NEW.coitem_cohead_id)
          AND (coitem_linenumber = NEW.coitem_linenumber)
          AND (coitem_subnumber > 0));
      END IF;
    END IF;
    IF (TG_OP = 'UPDATE') THEN
      IF (NEW.coitem_qtyord <> OLD.coitem_qtyord) THEN
  -- Recreate Sub Lines for Kit Components
      FOR _coitemid IN
        SELECT coitem_id
        FROM coitem
        WHERE ( (coitem_cohead_id=OLD.coitem_cohead_id)
          AND   (coitem_linenumber=OLD.coitem_linenumber)
          AND   (coitem_subnumber > 0) )
        LOOP
          SELECT deleteSoItem(_coitemid) INTO _result;
          IF (_result < 0) THEN
             RAISE EXCEPTION 'Error deleting kit components: deleteSoItem(integer) Error:%', _result;
          END IF;
        END LOOP;

        PERFORM explodeKit(NEW.coitem_cohead_id, NEW.coitem_linenumber, 0, NEW.coitem_itemsite_id,
                           NEW.coitem_qtyord, NEW.coitem_scheddate, NEW.coitem_promdate);
      END IF;
      IF ( (NEW.coitem_qtyord <> OLD.coitem_qtyord) OR
           (NEW.coitem_cos_accnt_id <> OLD.coitem_cos_accnt_id) ) THEN
        IF (fetchMetricBool('KitComponentInheritCOS')) THEN
  -- Update kit line item COS
          UPDATE coitem
          SET coitem_cos_accnt_id = CASE WHEN (COALESCE(NEW.coitem_cos_accnt_id, -1) != -1)
                                           THEN NEW.coitem_cos_accnt_id
                                         WHEN (NEW.coitem_warranty)
                                           THEN resolveCOWAccount(NEW.coitem_itemsite_id, _r.cohead_cust_id, _r.cohead_saletype_id, _r.cohead_shipzone_id)
                                         ELSE resolveCOSAccount(NEW.coitem_itemsite_id, _r.cohead_cust_id, _r.cohead_saletype_id, _r.cohead_shipzone_id)
                                    END
          WHERE((coitem_cohead_id=NEW.coitem_cohead_id)
            AND (coitem_linenumber = NEW.coitem_linenumber)
            AND (coitem_subnumber > 0));
        END IF;
      END IF;
      IF (NEW.coitem_scheddate <> OLD.coitem_scheddate) THEN
  -- Update kit line item Schedule Date
        UPDATE coitem
        SET coitem_scheddate = NEW.coitem_scheddate
        WHERE((coitem_cohead_id=NEW.coitem_cohead_id)
          AND (coitem_linenumber = NEW.coitem_linenumber)
          AND (coitem_subnumber > 0));
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    -- Create Purchase Request if flagged to do so
    IF ((NEW.coitem_order_type='R') AND (NEW.coitem_order_id=-1)) THEN
      SELECT createpr(CAST(cohead_number AS INTEGER), 'S', NEW.coitem_id) INTO _orderid
      FROM cohead
      WHERE (cohead_id=NEW.coitem_cohead_id);
      IF (_orderid > 0) THEN
        UPDATE coitem SET coitem_order_id=_orderid
        WHERE (coitem_id=NEW.coitem_id);
      END IF;
    END IF;

    -- Create Purchase Order if flagged to do so
    IF ((NEW.coitem_order_type='P') AND (NEW.coitem_order_id=-1)) THEN
      SELECT itemsrc_id INTO _itemsrcid
      FROM itemsite JOIN itemsrc ON (itemsrc_item_id=itemsite_item_id AND itemsrc_default)
      WHERE (itemsite_id=NEW.coitem_itemsite_id);
      IF (FOUND) THEN
        SELECT createPurchaseToSale(NEW.coitem_id,
                                    _itemsrcid,
                                    itemsite_dropship,
                                    CASE WHEN (NEW.coitem_prcost=0.0) THEN NULL
                                         ELSE NEW.coitem_prcost
                                    END) INTO _orderid
        FROM itemsite
        WHERE (itemsite_id=NEW.coitem_itemsite_id);
        IF (_orderid > 0) THEN
          UPDATE coitem SET coitem_order_id=_orderid
          WHERE (coitem_id=NEW.coitem_id);
        END IF;
      END IF;
    END IF;
  END IF;

  IF (_purchase) THEN
    --For purchase item processing
--    IF (fetchmetricbool('EnableDropShipments')) THEN
--      --Dropship processing
      IF(_po) THEN
        IF (TG_OP = 'UPDATE') THEN
          IF ((NEW.coitem_qtyord <> OLD.coitem_qtyord) OR (NEW.coitem_qty_invuomratio <> OLD.coitem_qty_invuomratio) OR (NEW.coitem_scheddate <> OLD.coitem_scheddate)) THEN
            --Update related poitem
            UPDATE poitem
            SET poitem_qty_ordered = roundQty(_fractional, (NEW.coitem_qtyord * NEW.coitem_qty_invuomratio / poitem_invvenduomratio)),
                poitem_duedate = NEW.coitem_scheddate 
            WHERE (poitem_id = OLD.coitem_order_id);

            --Generate the PoItemUpdatedBySo event
            INSERT INTO evntlog
                        ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
                          evntlog_number )
            SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
              'P', poitem_id, itemsite_warehous_id,
            (pohead_number || '-'|| poitem_linenumber || ': ' || item_number)
            FROM evntnot JOIN evnttype ON (evntnot_evnttype_id=evnttype_id)
                 JOIN itemsite ON (evntnot_warehous_id=itemsite_warehous_id)
                 JOIN item ON (itemsite_item_id=item_id)
                 JOIN poitem ON (poitem_itemsite_id=itemsite_id)
                 JOIN pohead ON (poitem_pohead_id=pohead_id)
            WHERE( (poitem_id=OLD.coitem_order_id)
            AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
            AND (evnttype_name='PoItemUpdatedBySo') );
          END IF;

          --If soitem is cancelled
          IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
            --Generate the PoItemSoCancelled event
            INSERT INTO evntlog
                        ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
                          evntlog_number )
            SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
            'P', poitem_id, itemsite_warehous_id,
            (pohead_number || '-' || poitem_linenumber || ': ' || item_number)
            FROM evntnot JOIN evnttype ON (evntnot_evnttype_id=evnttype_id)
                 JOIN itemsite ON (evntnot_warehous_id=itemsite_warehous_id)
                 JOIN item ON (itemsite_item_id=item_id)
                 JOIN poitem ON (poitem_itemsite_id=itemsite_id)
            JOIN pohead ON( poitem_pohead_id=pohead_id)
            WHERE( (poitem_id=OLD.coitem_order_id)
            AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
            AND (evnttype_name='PoItemSoCancelled') );
          END IF;
        END IF;
      END IF; 
--    END IF;
  END IF;

  IF (_rec.coitem_subnumber > 0) THEN
    SELECT coitem_status
      INTO _kstat
      FROM coitem
     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
       AND (coitem_linenumber=_rec.coitem_linenumber)
       AND (coitem_subnumber = 0));
    IF ((SELECT count(*)
           FROM coitem
          WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
            AND (coitem_linenumber=_rec.coitem_linenumber)
            AND (coitem_subnumber <> _rec.coitem_subnumber)
            AND (coitem_subnumber > 0)
            AND (coitem_status = 'O'))) > 0) THEN
      _pstat := 'O';
    ELSE
      _pstat := _rec.coitem_status;
    END IF;
  END IF;

  IF(TG_OP = 'INSERT') THEN
    IF (_rec.coitem_subnumber > 0 AND _rec.coitem_status = 'O') THEN
      _pstat := 'O';
    END IF;
  ELSIF (TG_OP = 'UPDATE') THEN
    IF (_rec.coitem_subnumber > 0 AND _rec.coitem_status = 'O') THEN
      _pstat := 'O';
    END IF;

    IF ((NEW.coitem_status = 'C') AND (OLD.coitem_status <> 'C')) THEN
      IF(_kit) THEN
        UPDATE coitem
           SET coitem_status='C'
         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
           AND (coitem_linenumber=OLD.coitem_linenumber)
           AND (coitem_status='O')
           AND (coitem_subnumber > 0));
      END IF;
    END IF;

    IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
      IF(_kit) THEN
        UPDATE coitem
           SET coitem_status='X'
         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
           AND (coitem_linenumber=OLD.coitem_linenumber)
           AND (coitem_status='O')
           AND (coitem_subnumber > 0));
      END IF;
    END IF;

    IF(NEW.coitem_status = 'O' AND OLD.coitem_status <> 'O') THEN
      IF(_kit) THEN
        UPDATE coitem
           SET coitem_status='O'
         WHERE((coitem_cohead_id=OLD.coitem_cohead_id)
           AND (coitem_linenumber=OLD.coitem_linenumber)
           AND ((coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) > 0)
           AND (coitem_subnumber > 0));
      END IF;
    END IF;

  END IF;

  IF ((_kstat IS NOT NULL) AND (_pstat IS NOT NULL) AND (_rec.coitem_subnumber > 0) AND (_kstat <> _pstat)) THEN
    UPDATE coitem
       SET coitem_status = _pstat
     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
       AND (coitem_linenumber=_rec.coitem_linenumber)
       AND (coitem_subnumber = 0));
  END IF;

  --If auto calculate freight, recalculate cohead_freight
  IF (SELECT cohead_calcfreight FROM cohead WHERE (cohead_id=NEW.coitem_cohead_id)) THEN
    UPDATE cohead SET cohead_freight = COALESCE(
      (SELECT SUM(freightdata_total) FROM freightDetail('SO',
                                                        cohead_id,
                                                        cohead_cust_id,
                                                        cohead_shipto_id,
                                                        cohead_orderdate,
                                                        cohead_shipvia,
                                                        cohead_curr_id)), 0)
    WHERE cohead_id=NEW.coitem_cohead_id;
  END IF;

  RETURN NEW;
END;

Function: public._soitembeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  _r              RECORD;
  _kit            BOOLEAN := FALSE;
  _shipped        BOOLEAN := FALSE;
  _coitemid       INTEGER := 0;
  _result         INTEGER := 0;

BEGIN

  -- Check Priv
  IF NOT (checkPrivilege('MaintainSalesOrders')) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Sales Order.';
  END IF;

  -- Cache some information
  SELECT * INTO _r
    FROM cohead, itemsite, item
   WHERE ( (cohead_id=OLD.coitem_cohead_id)
     AND   (itemsite_id=OLD.coitem_itemsite_id)
     AND   (item_id=itemsite_item_id) );

  _kit := (COALESCE(_r.item_type,'')='K');

  -- Check for shipped kit components
  IF(_kit AND OLD.coitem_status <> 'C' AND OLD.coitem_status <> 'X') THEN
    IF (EXISTS (SELECT coitem_id
                  FROM coitem JOIN shipitem ON (shipitem_orderitem_id=coitem_id)
                              JOIN shiphead ON (shiphead_id=shipitem_shiphead_id AND shiphead_order_type='SO')
                 WHERE ((coitem_cohead_id=OLD.coitem_cohead_id)
                   AND  (coitem_linenumber=OLD.coitem_linenumber)
                   AND (coitem_subnumber > 0))
              GROUP BY coitem_id
                HAVING (SUM(shipitem_qty) > 0)
                 LIMIT 1) ) THEN
      _shipped := TRUE;
    END IF;
  END IF;

  IF(_kit AND _shipped) THEN
    RAISE EXCEPTION 'You can not delete this Sales Order Line as it has several sub components that have already been shipped.';
  END IF;

  DELETE FROM comment
   WHERE ( (comment_source='SI')
     AND   (comment_source_id=OLD.coitem_id) );

  DELETE FROM charass
   WHERE ((charass_target_type='SI')
     AND  (charass_target_id=OLD.coitem_id));

  -- Delete Sub Lines for Kit Components
  FOR _coitemid IN
    SELECT coitem_id
      FROM coitem
     WHERE ( (coitem_cohead_id=OLD.coitem_cohead_id)
       AND   (coitem_linenumber=OLD.coitem_linenumber)
       AND   (coitem_subnumber > 0) )
    LOOP
    SELECT deleteSoItem(_coitemid) INTO _result;
    IF (_result < 0) THEN
      IF NOT (_r.itemsite_createsopo AND (_result = -10 OR _result = -20)) THEN
        RAISE EXCEPTION 'Error deleting kit components: deleteSoItem(integer) Error:%', _result;
      END IF;
    END IF;
  END LOOP;

  INSERT INTO evntlog ( evntlog_evnttime, evntlog_username,
                        evntlog_evnttype_id, evntlog_ordtype,
                        evntlog_ord_id, evntlog_warehous_id, evntlog_number )
  SELECT CURRENT_TIMESTAMP, evntnot_username,
	   evnttype_id, 'S',
	   OLD.coitem_id, _r.itemsite_warehous_id,
	   (_r.cohead_number || '-' || OLD.coitem_linenumber)
    FROM evntnot, evnttype
   WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND   (evntnot_warehous_id=_r.itemsite_warehous_id)
     AND   (OLD.coitem_scheddate <= (CURRENT_DATE + _r.itemsite_eventfence))
     AND   (evnttype_name='SoitemCancelled') );

  RETURN OLD;
END;

Function: public._soitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check NUMERIC;
  _itemNumber TEXT;
  _r RECORD;
  _kit BOOLEAN;

BEGIN

  --Determine if this is a kit for later processing
  SELECT COALESCE(item_type,'')='K'
  INTO _kit
  FROM itemsite, item
  WHERE((itemsite_item_id=item_id)
  AND (itemsite_id=NEW.coitem_itemsite_id));
  _kit := COALESCE(_kit, false);
  
  IF (TG_OP = 'INSERT') THEN

    -- If this is imported, go ahead and insert default characteristics
    IF (NEW.coitem_imported) THEN
      INSERT INTO charass (charass_target_type, charass_target_id, charass_char_id, charass_value, charass_price)
      SELECT 'SI', NEW.coitem_id, char_id, charass_value,
             itemcharprice(item_id,char_id,charass_value,cohead_cust_id,cohead_shipto_id,NEW.coitem_qtyord,cohead_curr_id,cohead_orderdate) 
        FROM (
           SELECT DISTINCT char_id, char_name, charass_value, item_id, cohead_cust_id, cohead_shipto_id, cohead_curr_id, cohead_orderdate
             FROM cohead, charass, char, itemsite, item
            WHERE((itemsite_id=NEW.coitem_itemsite_id)
              AND (itemsite_item_id=item_id)
              AND (charass_target_type='I') 
              AND (charass_target_id=item_id)
              AND (charass_default)
              AND (char_id=charass_char_id)
              AND (cohead_id=NEW.coitem_cohead_id))
           ORDER BY char_name) AS data;
    END IF;
  END IF;

  -- Create work order and process if flagged to do so
  IF ((NEW.coitem_order_type='W') AND (NEW.coitem_order_id=-1)) THEN
    SELECT createwo(CAST(cohead_number AS INTEGER),
                    NEW.coitem_itemsite_id,
                    1, -- priority
		    validateOrderQty(NEW.coitem_itemsite_id, NEW.coitem_qtyord, TRUE),
                    itemsite_leadtime,
                    NEW.coitem_scheddate,
		    NEW.coitem_memo,
                    'S',
                    NEW.coitem_id,
		    cohead_prj_id) INTO NEW.coitem_order_id
    FROM cohead, itemsite 
    WHERE ((cohead_id=NEW.coitem_cohead_id)
    AND (itemsite_id=NEW.coitem_itemsite_id));

    INSERT INTO charass
      (charass_target_type, charass_target_id,
       charass_char_id, charass_value) 
       SELECT 'W', NEW.coitem_order_id, charass_char_id, charass_value
       FROM charass
       WHERE ((charass_target_type='SI')
       AND  (charass_target_id=NEW.coitem_id));
  END IF;
   
  IF (TG_OP = 'UPDATE') THEN
--  Update P/R date if applicable

    IF (NEW.coitem_scheddate <> OLD.coitem_scheddate AND NEW.coitem_order_type='R' AND NEW.coitem_order_id > 1) THEN
      UPDATE pr SET pr_duedate = NEW.coitem_scheddate WHERE (pr_order_id=NEW.coitem_id AND pr_order_type='S');
    END IF;
    
--  If closing or cancelling and there is a job item work order, then close job and distribute remaining costs
    IF ((NEW.coitem_status = 'C' AND OLD.coitem_status <> 'C')
     OR (NEW.coitem_status = 'X' AND OLD.coitem_status <> 'X'))
     AND (OLD.coitem_order_id > -1) THEN

      SELECT wo_id, wo_wipvalue INTO _r
       FROM wo,itemsite,item
      WHERE ((wo_ordtype='S')
      AND (wo_ordid=OLD.coitem_id)
      AND (itemsite_id=wo_itemsite_id)
      AND (item_id=itemsite_item_id)
      AND (itemsite_costmethod = 'J'));

      IF (FOUND) THEN
        IF (_r.wo_wipvalue > 0) THEN
        --  Distribute to G/L, debit Cost of Sales, credit WIP
          PERFORM MIN(insertGLTransaction( 'W/O', 'WO', formatWoNumber(NEW.coitem_order_id), 'Job Closed Incomplete',
                                           costcat_wip_accnt_id,
                                           CASE WHEN (COALESCE(NEW.coitem_cos_accnt_id, -1) != -1)
                                                  THEN NEW.coitem_cos_accnt_id
                                                WHEN (NEW.coitem_warranty=TRUE)
                                                  THEN resolveCOWAccount(itemsite_id, cohead_cust_id, cohead_saletype_id, cohead_shipzone_id)
                                                ELSE resolveCOSAccount(itemsite_id, cohead_cust_id, cohead_saletype_id, cohead_shipzone_id)
                                           END,
                                           -1,  _r.wo_wipvalue, current_date ))
          FROM itemsite, costcat, cohead
          WHERE ((itemsite_id=NEW.coitem_itemsite_id)
           AND (itemsite_costcat_id=costcat_id)
           AND (cohead_id=NEW.coitem_cohead_id));
        END IF;

        UPDATE wo SET
          wo_status = 'C',
          wo_wipvalue = 0
        WHERE (wo_id = _r.wo_id);

      END IF;
    END IF;

--  Likewise, reopen the job if line reopened
    IF ((NEW.coitem_status != 'C' AND OLD.coitem_status = 'C')
     OR (NEW.coitem_status != 'X' AND OLD.coitem_status = 'X'))
     AND (OLD.coitem_order_id > -1) THEN
        UPDATE wo SET
          wo_status = 'I'
        FROM itemsite, item
        WHERE ((wo_ordtype = 'S')
         AND (wo_ordid=NEW.coitem_id)
         AND (wo_itemsite_id=itemsite_id)
         AND (itemsite_item_id=item_id)
         AND (itemsite_costmethod='J'));
    END IF;

--  Handle links to Return Authorization
    IF (fetchMetricBool('EnableReturnAuth')) THEN 
      SELECT * INTO _r 
      FROM raitem,rahead 
      WHERE ((raitem_new_coitem_id=NEW.coitem_id)
      AND (rahead_id=raitem_rahead_id));
      IF (FOUND) THEN
        IF ((_r.raitem_qtyauthorized <> NEW.coitem_qtyord OR
            _r.raitem_qty_uom_id <> NEW.coitem_qty_uom_id OR
            _r.raitem_qty_invuomratio <> NEW.coitem_qty_invuomratio OR
            _r.raitem_price_uom_id <> NEW.coitem_price_uom_id OR
            _r.raitem_price_invuomratio <> NEW.coitem_price_invuomratio)
            AND NOT (NEW.coitem_status = 'X' AND _r.raitem_qtyauthorized = 0)) THEN
          RAISE EXCEPTION 'Quantities for line item % may only be changed on the Return Authorization that created it.',NEW.coitem_linenumber;
        END IF;
        IF (OLD.coitem_warranty <> NEW.coitem_warranty) THEN
          UPDATE raitem SET raitem_warranty = NEW.coitem_warranty
           WHERE((raitem_new_coitem_id=NEW.coitem_id)
             AND (raitem_warranty != NEW.coitem_warranty));
        END IF;
        IF (OLD.coitem_cos_accnt_id <> NEW.coitem_cos_accnt_id) THEN
          UPDATE raitem SET raitem_cos_accnt_id = NEW.coitem_cos_accnt_id
           WHERE((raitem_new_coitem_id=NEW.coitem_id)
             AND (COALESCE(raitem_cos_accnt_id,-1) != COALESCE(NEW.coitem_cos_accnt_id,-1)));
        END IF;
        IF (OLD.coitem_taxtype_id <> NEW.coitem_taxtype_id) THEN
          UPDATE raitem SET raitem_taxtype_id = NEW.coitem_taxtype_id
           WHERE((raitem_new_coitem_id=NEW.coitem_id)
             AND (COALESCE(raitem_taxtype_id,-1) != COALESCE(NEW.coitem_taxtype_id,-1)));
        END IF;
        IF (OLD.coitem_scheddate <> NEW.coitem_scheddate) THEN
          UPDATE raitem SET raitem_scheddate = NEW.coitem_scheddate
           WHERE((raitem_new_coitem_id=NEW.coitem_id)
             AND (raitem_scheddate != NEW.coitem_scheddate));
        END IF;
        IF (OLD.coitem_memo <> NEW.coitem_memo) THEN
          UPDATE raitem SET raitem_notes = NEW.coitem_memo
           WHERE((raitem_new_coitem_id=NEW.coitem_id)
             AND (raitem_notes != NEW.coitem_memo));
        END IF;
        IF ((OLD.coitem_qtyshipped <> NEW.coitem_qtyshipped) AND 
           (NEW.coitem_qtyshipped >= _r.raitem_qtyauthorized) AND
           ((_r.raitem_disposition = 'S') OR
           (_r.raitem_status = 'O') AND
           (_r.raitem_disposition IN ('P','V')) AND
           (_r.raitem_qtyreceived >= _r.raitem_qtyauthorized))) THEN
          UPDATE raitem SET raitem_status = 'C' 
          WHERE (raitem_new_coitem_id=NEW.coitem_id);
        END IF;
      END IF;
    END IF; 
  END IF; 

  RETURN NEW;
END;

Function: public._soitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _changelog BOOLEAN := FALSE;
  _check BOOLEAN;
  _kit BOOLEAN;
  _shipped BOOLEAN;
  _atShipping NUMERIC;
  _tmp INTEGER;
  _rec RECORD;
BEGIN
  -- Check
  SELECT checkPrivilege('MaintainSalesOrders') OR checkPrivilege('ShipOrders') OR checkPrivilege('IssueStockToShipping') INTO _check;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to alter a Sales Order.';
  END IF;

  IF ( SELECT fetchMetricBool('SalesOrderChangeLog') ) THEN
    _changelog := TRUE;
  END IF;

  IF (TG_OP IN ('INSERT','UPDATE')) THEN
    IF (NEW.coitem_scheddate IS NULL) THEN
      IF (fetchmetricbool('AllowASAPShipSchedules')) THEN
        NEW.coitem_scheddate := current_date;
      ELSE
        RAISE EXCEPTION 'A schedule date is required.';
      END IF;
    END IF;
  END IF;

  _rec := NEW;

  SELECT COALESCE(item_type,'')='K'
    INTO _kit
    FROM itemsite, item
   WHERE((itemsite_item_id=item_id)
     AND (itemsite_id=_rec.coitem_itemsite_id));
  _kit := COALESCE(_kit, false);
  _shipped := false;
  IF(_kit AND _rec.coitem_status <> 'C' AND _rec.coitem_status <> 'X') THEN
    SELECT coitem_id
      INTO _tmp
      FROM coitem JOIN shipitem ON (shipitem_orderitem_id=coitem_id)
                  JOIN shiphead ON (shiphead_id=shipitem_shiphead_id AND shiphead_order_type='SO')
     WHERE((coitem_cohead_id=_rec.coitem_cohead_id)
       AND (coitem_linenumber=_rec.coitem_linenumber)
       AND (coitem_subnumber > 0))
     GROUP BY coitem_id
    HAVING (SUM(shipitem_qty) > 0)
     LIMIT 1;
    IF (FOUND) THEN
      _shipped := true;
    END IF;
  END IF;
  
  IF (TG_OP ='UPDATE') THEN
    IF ((OLD.coitem_status <> 'C') AND (NEW.coitem_status = 'C')) THEN
      SELECT qtyAtShipping(NEW.coitem_id) INTO _atShipping;
      IF (_atShipping > 0) THEN
        RAISE EXCEPTION 'Line % cannot be Closed at this time as there is inventory at shipping.',NEW.coitem_linenumber;
      END IF;
    END IF;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                          evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber)
    FROM evntnot, evnttype, itemsite, item, cohead
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (itemsite_id=NEW.coitem_itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (NEW.coitem_cohead_id=cohead_id)
     AND (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
     AND (evnttype_name='SoitemCreated') );

    IF (_changelog) THEN
      PERFORM postComment('ChangeLog', 'SI', NEW.coitem_id, 'Created');
    END IF;

    --Set defaults if no values passed
    NEW.coitem_linenumber	:= COALESCE(NEW.coitem_linenumber,
                                          (SELECT (COALESCE(MAX(coitem_linenumber), 0) + 1)
                                           FROM coitem
                                           WHERE (coitem_cohead_id=NEW.coitem_cohead_id)));
    NEW.coitem_status		:= COALESCE(NEW.coitem_status,'O');
    NEW.coitem_scheddate	:= COALESCE(NEW.coitem_scheddate,
					   (SELECT MIN(coitem_scheddate)
					    FROM coitem
					    WHERE (coitem_cohead_id=NEW.coitem_cohead_id)));
    NEW.coitem_memo		:= COALESCE(NEW.coitem_memo,'');
    NEW.coitem_prcost		:= COALESCE(NEW.coitem_prcost,0);
    NEW.coitem_warranty	:= COALESCE(NEW.coitem_warranty,false);

    IF (NEW.coitem_status='O') THEN
      UPDATE cohead SET cohead_status = 'O'
       WHERE ((cohead_id=NEW.coitem_cohead_id)
         AND  (cohead_status='C'));
    END IF;

    RETURN NEW;

  ELSIF (TG_OP = 'UPDATE') THEN
    IF (NEW.coitem_qtyord <> OLD.coitem_qtyord) THEN
      IF(_kit) THEN
        IF(_shipped) THEN
          RAISE EXCEPTION 'You can not change the qty ordered for a Kit item when one or more of its components have shipped inventory.';
        END IF;
      END IF;
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
			    evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
			    evntlog_oldvalue, evntlog_newvalue )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
	     'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber),
	     OLD.coitem_qtyord, NEW.coitem_qtyord
      FROM evntnot, evnttype, itemsite, item, cohead
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=itemsite_warehous_id)
       AND (itemsite_id=NEW.coitem_itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (NEW.coitem_cohead_id=cohead_id)
       AND ( (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
	OR   (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence)) )
       AND (evnttype_name='SoitemQtyChanged') );

      IF (_changelog) THEN
	PERFORM postComment( 'ChangeLog', 'SI', NEW.coitem_id,
			     ( 'Changed Qty. Ordered from ' || formatQty(OLD.coitem_qtyord) ||
			       ' to ' || formatQty(NEW.coitem_qtyord) ) );
      END IF;

    END IF;

    IF (NEW.coitem_scheddate <> OLD.coitem_scheddate) THEN
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
			    evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
			    evntlog_olddate, evntlog_newdate )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
	     'S', NEW.coitem_id, itemsite_warehous_id, (cohead_number || '-' || NEW.coitem_linenumber),
	     OLD.coitem_scheddate, NEW.coitem_scheddate
      FROM evntnot, evnttype, itemsite, item, cohead
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=itemsite_warehous_id)
       AND (itemsite_id=NEW.coitem_itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (NEW.coitem_cohead_id=cohead_id)
       AND ( (NEW.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
	OR   (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence)) )
       AND (evnttype_name='SoitemSchedDateChanged') );

      IF (_changelog) THEN
	PERFORM postComment( 'ChangeLog', 'SI', NEW.coitem_id,
			     ( 'Changed Sched. Date from ' || formatDate(OLD.coitem_scheddate) ||
			       ' to ' || formatDate(NEW.coitem_scheddate)) );
      END IF;

    END IF;

    IF ((NEW.coitem_status = 'C') AND (OLD.coitem_status <> 'C')) THEN
      NEW.coitem_closedate = CURRENT_TIMESTAMP;
      NEW.coitem_close_username = getEffectiveXtUser();
      NEW.coitem_qtyreserved := 0;

      IF (_changelog) THEN
	PERFORM postComment('ChangeLog', 'SI', NEW.coitem_id, 'Closed');
      END IF;
    END IF;

    IF ((NEW.coitem_status <> 'C') AND (OLD.coitem_status = 'C')) THEN
      NEW.coitem_closedate = NULL;
      NEW.coitem_close_username = NULL;

      IF (_changelog) THEN
	PERFORM postComment('ChangeLog', 'SI', NEW.coitem_id, 'Reopened');
      END IF;
    END IF;

    IF ((NEW.coitem_status = 'X') AND (OLD.coitem_status <> 'X')) THEN
      IF ((OLD.coitem_order_type = 'W') AND
	  (SELECT wo_status IN ('O', 'E', 'R')
	    FROM wo
	    WHERE (wo_id=OLD.coitem_order_id))) THEN
      -- Close any associated W/O
        PERFORM closeWo(OLD.coitem_order_id, FALSE, CURRENT_DATE);
      ELSIF (OLD.coitem_order_type = 'R') THEN 
      -- Delete any associated P/R
        PERFORM deletePr(OLD.coitem_order_id);
      END IF;

      NEW.coitem_qtyreserved := 0;

      IF (_changelog) THEN
	PERFORM postComment('ChangeLog', 'SI', NEW.coitem_id, 'Canceled');
	PERFORM postComment('ChangeLog', 'S', NEW.coitem_cohead_id, 'Line # '|| NEW.coitem_linenumber ||' Canceled');
      END IF;

      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username,
			    evntlog_evnttype_id, evntlog_ordtype,
			    evntlog_ord_id, evntlog_warehous_id, evntlog_number )
      SELECT CURRENT_TIMESTAMP, evntnot_username,
	     evnttype_id, 'S',
	     OLD.coitem_id, itemsite_warehous_id,
	     (cohead_number || '-' || OLD.coitem_linenumber)
      FROM evntnot, evnttype, itemsite, item, cohead
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=itemsite_warehous_id)
       AND (itemsite_id=OLD.coitem_itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (OLD.coitem_cohead_id=cohead_id)
       AND (OLD.coitem_scheddate <= (CURRENT_DATE + itemsite_eventfence))
       AND (evnttype_name='SoitemCancelled') );

    END IF;

    IF ((NEW.coitem_qtyreserved <> OLD.coitem_qtyreserved) AND (_changelog)) THEN
      PERFORM postComment('ChangeLog', 'SI', NEW.coitem_id, 'Changed Qty Reserved to '|| NEW.coitem_qtyreserved);
    END IF;

  END IF;

  NEW.coitem_lastupdated = CURRENT_TIMESTAMP;

  -- Handle status for header
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.coitem_status <> NEW.coitem_status) THEN
      IF ( (SELECT (count(*) < 1)
              FROM coitem
             WHERE ((coitem_cohead_id=NEW.coitem_cohead_id)
               AND  (coitem_id != NEW.coitem_id)
               AND  (coitem_status='O')) ) AND (NEW.coitem_status<>'O') ) THEN
        UPDATE cohead SET cohead_status = 'C'
         WHERE ((cohead_id=NEW.coitem_cohead_id)
           AND  (cohead_status='O'));
      ELSE
        UPDATE cohead SET cohead_status = 'O'
         WHERE ((cohead_id=NEW.coitem_cohead_id)
           AND  (cohead_status='C'));
      END IF;
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public._taxauthafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (EXISTS(SELECT 1
               FROM checkhead
              WHERE checkhead_recip_id = OLD.taxauth_id
                AND checkhead_recip_type='T')) THEN
    RAISE EXCEPTION 'Cannot delete the tax authority % because checks have been written to it [xtuple: deleteTaxAuthority, -7, %]',
                    OLD.taxauth_number, OLD.taxauth_number;
  END IF;

  IF (fetchMetricValue('DefaultTaxAuthority') = OLD.taxauth_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Tax Authority [xtuple: deleteTaxAuthority, -8, %]',
                    OLD.taxauth_code;
  END IF;

  IF (fetchMetricBool('TaxAuthChangeLog')) THEN
    PERFORM postComment(cmnttype_id, 'TAXAUTH', OLD.taxauth_id,
                        'Deleted "' || OLD.taxauth_number || '"')
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');
  END IF;

  RETURN OLD;
END;

Function: public._taxauthaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN
  IF (TG_OP = 'INSERT') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_taxauth_id=NEW.taxauth_id,
                         crmacct_name=NEW.taxauth_name
       WHERE crmacct_number=NEW.taxauth_code;
      IF (FOUND) THEN
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,   crmacct_name,     crmacct_active,
                            crmacct_type,     crmacct_taxauth_id
                  ) VALUES (NEW.taxauth_code, NEW.taxauth_name, TRUE, 
                            'O',              NEW.taxauth_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    /* TODO: default characteristic assignments based on what? */

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.taxauth_code
    WHERE ((crmacct_taxauth_id=NEW.taxauth_id)
      AND  (crmacct_number!=NEW.taxauth_code));

    UPDATE crmacct SET crmacct_name = NEW.taxauth_name
    WHERE ((crmacct_taxauth_id=NEW.taxauth_id)
      AND  (crmacct_name!=NEW.taxauth_name));

  END IF;

  IF (fetchMetricBool('TaxAuthChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.taxauth_code <> NEW.taxauth_code) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'Code changed from "' || OLD.taxauth_code ||
                              '" to "' || NEW.taxauth_code || '"');
        END IF;

        IF (OLD.taxauth_name <> NEW.taxauth_name) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'Name changed from "' || OLD.taxauth_name ||
                              '" to "' || NEW.taxauth_name || '"');
        END IF;

        IF (OLD.taxauth_extref <> NEW.taxauth_extref) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'External Ref. changed from "' || OLD.taxauth_extref ||
                              '" to "' || NEW.taxauth_extref || '"');
        END IF;

        IF (OLD.taxauth_addr_id <> NEW.taxauth_addr_id) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'Address changed from ' || formatAddr(OLD.taxauth_addr_id)
                              || ' to ' || formatAddr(NEW.taxauth_addr_id));
        END IF;

        IF (OLD.taxauth_curr_id <> NEW.taxauth_curr_id) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'Currency changed from "' ||
                              currConcat(OLD.taxauth_curr_id) || '" to "' ||
                              currConcat(NEW.taxauth_curr_id) || '"');
        END IF;

        IF (OLD.taxauth_county <> NEW.taxauth_county) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'County changed from "' || OLD.taxauth_county ||
                              '" to "' || NEW.taxauth_county || '"');
        END IF;

        IF (OLD.taxauth_accnt_id <> NEW.taxauth_accnt_id) THEN
          PERFORM postComment(_cmnttypeid, 'TAXAUTH', NEW.taxauth_id,
                              'Account changed from "' ||
                              formatGLAccount(OLD.taxauth_accnt_id) || '" to "' ||
                              formatGLAccount(NEW.taxauth_accnt_id) || '"');
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._taxauthbeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainTaxAuthorities')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Tax Authorities.';
  END IF;

  UPDATE crmacct SET crmacct_taxauth_id = NULL
   WHERE crmacct_taxauth_id = OLD.taxauth_id;

  RETURN OLD;
END;

Function: public._taxauthbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (NOT checkPrivilege('MaintainTaxAuthorities')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Tax Authorities.';
  END IF;

  IF (NEW.taxauth_code IS NULL) THEN
    RAISE EXCEPTION 'You must supply a Tax Authority Code.';
  END IF;

  IF (TG_OP = 'INSERT' AND
      fetchMetricText('CRMAccountNumberGeneration') IN ('A','O')) THEN
    PERFORM clearNumberIssue('CRMAccountNumber', NEW.taxauth_code);
  END IF;

  NEW.taxauth_code := UPPER(NEW.taxauth_code);

  RETURN NEW;
END;

Function: public._termsafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (fetchMetricValue('DefaultTerms') = OLD.terms_id) THEN
    RAISE EXCEPTION 'Cannot delete the default Terms [xtuple: terms, -1, %]',
                    OLD.terms_code;
  END IF;

  RETURN OLD;
END;

Function: public._todoitemtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _recurid     INTEGER;
  _newparentid INTEGER;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    SELECT recur_id INTO _recurid
      FROM recur
     WHERE ((recur_parent_id=OLD.todoitem_id)
       AND  (recur_parent_type='TODO'));

    IF (_recurid IS NOT NULL) THEN
      RAISE DEBUG 'recur_id for deleted todoitem = %', _recurid;

      SELECT todoitem_id INTO _newparentid
        FROM todoitem
       WHERE ((todoitem_recurring_todoitem_id=OLD.todoitem_id)
          AND (todoitem_id!=OLD.todoitem_id))
       ORDER BY todoitem_due_date
       LIMIT 1;

      RAISE DEBUG '_newparentid for deleted todoitem = %', COALESCE(_newparentid, NULL);

      -- client is responsible for warning about deleting a recurring todoitem
      IF (_newparentid IS NULL) THEN
        DELETE FROM recur WHERE recur_id=_recurid;
      ELSE
        UPDATE recur SET recur_parent_id=_newparentid
         WHERE recur_id=_recurid;

        UPDATE todoitem SET todoitem_recurring_todoitem_id=_newparentid
         WHERE todoitem_recurring_todoitem_id=OLD.todoitem_id
           AND todoitem_id != OLD.todoitem_id;

        RAISE DEBUG 'reparented recurrence';
      END IF;
    END IF;

    DELETE FROM alarm
     WHERE ((alarm_source='TODO')
        AND (alarm_source_id=OLD.todoitem_id));

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._uomconvupdate()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
 
  UPDATE itemuomconv
  SET itemuomconv_to_value = NEW.uomconv_to_value,
  itemuomconv_from_value = NEW.uomconv_from_value,
  itemuomconv_fractional = NEW.uomconv_fractional
  WHERE((itemuomconv_from_uom_id = NEW.uomconv_from_uom_id)
  AND (itemuomconv_to_uom_id = NEW.uomconv_to_uom_id));

RETURN NEW;

END; 

Function: public._usrprefaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    IF (NEW.usrpref_name='active') THEN
      LOOP
        UPDATE crmacct SET crmacct_usr_username=NEW.usrpref_username
         WHERE crmacct_number=UPPER(NEW.usrpref_username);
        IF (FOUND) THEN
          EXIT;
        END IF;
        BEGIN
          INSERT INTO crmacct(crmacct_number,        crmacct_active,
                              crmacct_type,          crmacct_usr_username
                    ) VALUES (NEW.usrpref_username,  NEW.usrpref_value::BOOL,
                              'I',                   NEW.usrpref_username);
          EXIT;
        EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
        END;
      END LOOP;

    ELSIF (NEW.usrpref_name='propername') THEN
      LOOP
        UPDATE crmacct SET crmacct_name=NEW.usrpref_value
         WHERE crmacct_number=UPPER(NEW.usrpref_username);
        IF (FOUND) THEN
          EXIT;
        END IF;
        BEGIN
          INSERT INTO crmacct(crmacct_number,        crmacct_active,
                              crmacct_name,
                              crmacct_type,          crmacct_usr_username
                    ) VALUES (UPPER(NEW.usrpref_username), TRUE,
                              NEW.usrpref_value,
                              'I',                   NEW.usrpref_username);
          EXIT;
        EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
        END;
      END LOOP;

    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._usrprefbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF NOT (checkPrivilege('MaintainUsers') OR
          checkPrivilege('MaintainPreferencesOthers') OR
          (checkPrivilege('MaintainPreferencesSelf'))) THEN
    -- 2 IFs because plpgsql doesn't always evaluate boolean exprs left-to-right
    IF (TG_OP = 'DELETE') THEN
      IF NOT (OLD.usrpref_name LIKE '%/checked' OR OLD.usrpref_name LIKE '%/columnsShown') THEN
        RAISE EXCEPTION 'You do not have privileges to change this User Preference.';
      END IF;
    ELSIF (NEW.usrpref_username = getEffectiveXtUser()) THEN
      IF NOT (NEW.usrpref_name LIKE '%/checked' OR NEW.usrpref_name LIKE '%/columnsShown') THEN
        RAISE EXCEPTION 'You do not have privileges to change this User Preference.';
      END IF;
    END IF;
  END IF;

  IF (TG_OP IN ('INSERT', 'UPDATE')) THEN
    IF (NEW.usrpref_name = 'locale') THEN
      IF NOT EXISTS(SELECT locale_id
                      FROM locale
                     WHERE locale_id = NEW.usrpref_value::INTEGER) THEN
        RAISE EXCEPTION 'You must supply a valid Locale.';
      END IF;

    ELSIF (NEW.usrpref_name IN ('agent', 'active')) THEN
      IF (NEW.usrpref_value NOT IN ('t', 'f')) THEN
        RAISE EXCEPTION '% must be either "t" or "f"', NEW.usrpref_name;
      END IF;
    END IF;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._usrprivtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check BOOLEAN;
  _returnVal INTEGER;
BEGIN
  -- This looks like a candidate for a foreign key but isn't.
  -- fkeys don't work if the foreign key value resides in a child of the 
  -- table and not the table itself.
  IF ((TG_OP = 'UPDATE' OR TG_OP = 'INSERT') AND
      (NOT EXISTS(SELECT priv_id
                  FROM priv
                  WHERE (priv_id=NEW.usrpriv_priv_id)))) THEN
    RAISE EXCEPTION 'Privilege id % does not exist or is part of a disabled package.',
                NEW.usrpriv_priv_id;
    RETURN OLD;

  ELSIF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._vendaddrtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _vendname   TEXT;

BEGIN

--  Checks
  SELECT checkPrivilege('MaintainVendors') INTO _check;
  IF NOT (_check) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Vendors.';
  END IF;

  IF (TG_OP IN ('INSERT','UPDATE')) THEN

    IF (LENGTH(COALESCE(NEW.vendaddr_code, ''))=0) THEN
      RAISE EXCEPTION 'You must supply a valid Vendor Address Number.';
    END IF;

    IF (LENGTH(COALESCE(NEW.vendaddr_name, ''))=0) THEN
      RAISE EXCEPTION 'You must supply a valid Vendor Address Name.';
    END IF;

    IF (NEW.vendaddr_vend_id IS NULL) THEN
      RAISE EXCEPTION 'You must supply a valid Vendor ID.';
    END IF;

    SELECT vendaddr_code INTO _vendname
    FROM vendaddrinfo
    WHERE ( (vendaddr_vend_id=NEW.vendaddr_vend_id)
      AND (UPPER(vendaddr_code)=UPPER(NEW.vendaddr_code))
      AND (vendaddr_id<>NEW.vendaddr_id) );
    IF (FOUND) THEN
      RAISE EXCEPTION 'The Vendor Address Number entered cannot be used as it is in use.';
    END IF;

  END IF;
  
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._vendaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid   INTEGER;

BEGIN

  IF (TG_OP = 'INSERT') THEN
    -- http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#PLPGSQL-UPSERT-EXAMPLE
    LOOP
      UPDATE crmacct SET crmacct_vend_id=NEW.vend_id,
                         crmacct_name=NEW.vend_name
       WHERE crmacct_number=NEW.vend_number;
      IF (FOUND) THEN
        EXIT;
      END IF;
      BEGIN
        INSERT INTO crmacct(crmacct_number,     crmacct_name,    crmacct_active,
                            crmacct_type,       crmacct_vend_id,
                            crmacct_cntct_id_1, crmacct_cntct_id_2
                  ) VALUES (NEW.vend_number,    NEW.vend_name,   NEW.vend_active,
                            'O',                NEW.vend_id,
                            NEW.vend_cntct1_id, NEW.vend_cntct2_id);
        EXIT;
      EXCEPTION WHEN unique_violation THEN
            -- do nothing, and loop to try the UPDATE again
      END;
    END LOOP;

    /* TODO: default characteristic assignments based on vendgrp? */

  ELSIF (TG_OP = 'UPDATE') THEN
    UPDATE crmacct SET crmacct_number = NEW.vend_number
    WHERE ((crmacct_vend_id=NEW.vend_id)
      AND  (crmacct_number!=NEW.vend_number));

    UPDATE crmacct SET crmacct_name = NEW.vend_name
    WHERE ((crmacct_vend_id=NEW.vend_id)
      AND  (crmacct_name!=NEW.vend_name));

  END IF;

  IF (fetchMetricBool('VendorChangeLog')) THEN
    SELECT cmnttype_id INTO _cmnttypeid
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');

    IF (_cmnttypeid IS NOT NULL) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'V', NEW.vend_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN

        IF (OLD.vend_number <> NEW.vend_number) THEN
          PERFORM postComment(_cmnttypeid, 'V', NEW.vend_id,
                              ('Number Changed from "' || OLD.vend_number ||
                               '" to "' || NEW.vend_number || '"') );
        END IF;

        IF (OLD.vend_name <> NEW.vend_name) THEN
          PERFORM postComment( _cmnttypeid, 'V', NEW.vend_id,
                              ('Name Changed from "' || OLD.vend_name ||
                               '" to "' || NEW.vend_name || '"') );
        END IF;

        IF (OLD.vend_active <> NEW.vend_active) THEN
          PERFORM postComment(_cmnttypeid, 'V', NEW.vend_id,
                              CASE WHEN NEW.vend_active THEN 'Activated'
                                   ELSE 'Deactivated' END);
        END IF;

      END IF;
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._vendinfoafterdeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF EXISTS(SELECT 1
              FROM checkhead
             WHERE ((checkhead_recip_id=OLD.vend_id)
                AND (checkhead_recip_type='V'))) THEN
    RAISE EXCEPTION '[xtuple: deleteVendor, -7]';
  END IF;

  DELETE FROM taxreg
   WHERE ((taxreg_rel_type='V')
      AND (taxreg_rel_id=OLD.vend_id));

  IF (fetchMetricBool('VendorChangeLog')) THEN
    PERFORM postComment(cmnttype_id, 'V', OLD.vend_id,
                        ('Deleted "' || OLD.vend_number || '"'))
      FROM cmnttype
     WHERE (cmnttype_name='ChangeLog');
  END IF;

  RETURN OLD;
END;

Function: public._vendinfobeforedeletetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF NOT (checkPrivilege('MaintainVendors')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Vendors.';
  END IF;

  DELETE FROM itemsrcp
   WHERE itemsrcp_itemsrc_id IN (SELECT itemsrc_id
                                   FROM itemsrc
                                  WHERE itemsrc_vend_id=OLD.vend_id);

  DELETE FROM itemsrc WHERE (itemsrc_vend_id=OLD.vend_id);

  DELETE FROM vendaddrinfo WHERE (vendaddr_vend_id=OLD.vend_id);

  UPDATE crmacct SET crmacct_vend_id = NULL
   WHERE crmacct_vend_id = OLD.vend_id;
  RETURN OLD;
END;

Function: public._vendtrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  IF NOT (checkPrivilege('MaintainVendors')) THEN
    RAISE EXCEPTION 'You do not have privileges to maintain Vendors.';
  END IF;

  IF (LENGTH(COALESCE(NEW.vend_number, ''))=0) THEN
    RAISE EXCEPTION 'You must supply a valid Vendor Number.';
  END IF;

  IF (LENGTH(COALESCE(NEW.vend_name, ''))=0) THEN
    RAISE EXCEPTION 'You must supply a valid Vendor Name.';
  END IF;

  IF (NEW.vend_vendtype_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Vendor Type ID.';
  END IF;

  IF (NEW.vend_terms_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Terms Code ID.';
  END IF;

  IF (TG_OP = 'INSERT' AND fetchMetricText('CRMAccountNumberGeneration') IN ('A','O')) THEN
    PERFORM clearNumberIssue('CRMAccountNumber', NEW.vend_number);
  END IF;

  NEW.vend_number := UPPER(NEW.vend_number);

  RETURN NEW;
END;

Function: public._vodistaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;

BEGIN
  IF ( (TG_OP = 'UPDATE') OR (TG_OP = 'DELETE') ) THEN
    IF (OLD.vodist_tax_id <> -1) THEN
    -- Delete any existing voheadtax adjustment records
      DELETE FROM voheadtax
      WHERE ( (taxhist_parent_id=OLD.vodist_vohead_id)
        AND   (taxhist_tax_id=OLD.vodist_tax_id)
        AND   (taxhist_taxtype_id=getAdjustmentTaxTypeId()) );
    END IF;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

-- Cache Voucher Head
  SELECT * INTO _r
  FROM vohead
  WHERE (vohead_id=NEW.vodist_vohead_id);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Voucher head not found';
  END IF;

  IF (NEW.vodist_tax_id <> -1) THEN
  -- Insert adjustment voheadtax
    INSERT INTO voheadtax
      ( taxhist_parent_id,
        taxhist_taxtype_id,
        taxhist_tax_id,
        taxhist_basis,
        taxhist_basis_tax_id,
        taxhist_sequence,
        taxhist_percent,
        taxhist_amount,
        taxhist_tax,
        taxhist_docdate )
    VALUES
      ( NEW.vodist_vohead_id,
        getAdjustmentTaxTypeId(),
        NEW.vodist_tax_id,
        0,
        NULL,
        1,
        0,
        0,
        (NEW.vodist_amount * -1),
        _r.vohead_docdate );
  END IF;

  RETURN NEW;
END;

Function: public._vodistbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  IF (TG_OP = 'DELETE') THEN
    IF (OLD.vodist_tax_id <> -1) THEN
    -- Delete any existing voheadtax adjustment records
      DELETE FROM voheadtax
      WHERE ( (taxhist_parent_id=OLD.vodist_vohead_id)
        AND   (taxhist_tax_id=OLD.vodist_tax_id)
        AND   (taxhist_taxtype_id=getAdjustmentTaxTypeId()) );
    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._voheadaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (TG_OP = 'DELETE') THEN
    PERFORM releaseVoNumber(CAST(OLD.vohead_number AS INTEGER));
    RETURN OLD;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    PERFORM clearNumberIssue('VcNumber', NEW.vohead_number);
    RETURN NEW;
  END IF;

  IF (TG_OP = 'UPDATE') THEN
    IF ( (COALESCE(NEW.vohead_taxzone_id,-1) <> COALESCE(OLD.vohead_taxzone_id,-1)) OR
         (NEW.vohead_docdate <> OLD.vohead_docdate) OR
         (NEW.vohead_curr_id <> OLD.vohead_curr_id) ) THEN
      PERFORM calculateTaxHist( 'voitemtax',
                                voitem_id,
                                NEW.vohead_taxzone_id,
                                voitem_taxtype_id,
                                NEW.vohead_docdate,
                                NEW.vohead_curr_id,
                                (vodist_amount * -1) )
      FROM voitem JOIN vodist ON ( (vodist_vohead_id=voitem_vohead_id) AND
                                   (vodist_poitem_id=voitem_poitem_id) )
      WHERE (voitem_vohead_id = NEW.vohead_id);
    END IF;

    -- Touch any Misc Tax Distributions so voheadtax is recalculated
    IF (NEW.vohead_docdate <> OLD.vohead_docdate) THEN
      UPDATE vodist SET vodist_vohead_id=NEW.vohead_id
      WHERE ( (vodist_vohead_id=OLD.vohead_id)
        AND   (vodist_tax_id <> -1) );
    END IF;
  END IF;

  RETURN NEW;
END;

Function: public._voheadbeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _recurid     INTEGER;
  _newparentid INTEGER;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    /* TODO: is setting recv_invoiced and poreject_invoiced to FALSE correct?
             this behavior is inherited from the now-defunct deleteVoucher.
     */
    UPDATE recv SET recv_vohead_id = NULL,
                    recv_voitem_id = NULL,
                    recv_invoiced  = FALSE
     WHERE recv_vohead_id = OLD.vohead_id;

    UPDATE poreject SET poreject_vohead_id = NULL,
                        poreject_voitem_id = NULL,
                        poreject_invoiced  = FALSE
     WHERE poreject_vohead_id = OLD.vohead_id;

    DELETE FROM vodist    WHERE vodist_vohead_id  = OLD.vohead_id;
    DELETE FROM voheadtax WHERE taxhist_parent_id = OLD.vohead_id;
    DELETE FROM voitem    WHERE voitem_vohead_id  = OLD.vohead_id;

    SELECT recur_id INTO _recurid
      FROM recur
     WHERE ((recur_parent_id=OLD.vohead_id)
        AND (recur_parent_type='V'));
    IF (_recurid IS NOT NULL) THEN
      SELECT vohead_id INTO _newparentid
        FROM vohead
       WHERE ((vohead_recurring_vohead_id=OLD.vohead_id)
          AND (vohead_id!=OLD.vohead_id))
       ORDER BY vohead_docdate
       LIMIT 1;

      IF (_newparentid IS NULL) THEN
        DELETE FROM recur WHERE recur_id=_recurid;
      ELSE
        UPDATE recur SET recur_parent_id=_newparentid
         WHERE recur_id=_recurid;
        UPDATE vohead SET vohead_recurring_vohead_id=_newparentid
         WHERE vohead_recurring_vohead_id=OLD.vohead_id
           AND vohead_id!=OLD.vohead_id;
      END IF;
    END IF;

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._voitemaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;

BEGIN
  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  END IF;

-- Cache Voucher Head
  SELECT * INTO _r
  FROM vohead
  WHERE (vohead_id=NEW.voitem_vohead_id);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Voucher head not found';
  END IF;

-- Calculate Tax
  PERFORM calculateTaxHist( 'voitemtax',
                            NEW.voitem_id,
                            COALESCE(_r.vohead_taxzone_id, -1),
                            NEW.voitem_taxtype_id,
                            COALESCE(_r.vohead_docdate, CURRENT_DATE),
                            COALESCE(_r.vohead_curr_id, -1),
                            COALESCE(SUM(vodist_amount * -1), 0) )
  FROM vodist
  WHERE ( (vodist_vohead_id=_r.vohead_id)
    AND   (vodist_poitem_id=NEW.voitem_poitem_id) );

  RETURN NEW;
END;

Function: public._voitembeforetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  IF (TG_OP = 'DELETE') THEN
    DELETE FROM voitemtax
    WHERE (taxhist_parent_id=OLD.voitem_id);

    RETURN OLD;
  END IF;

  RETURN NEW;
END;

Function: public._warehoustrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;
  _check      BOOLEAN;
  _checkId    INTEGER;

BEGIN

  -- Checks
  -- Start with privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainWarehouses') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add new Sites.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainWarehouses') OR checkPrivilege('IssueCountTags') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Site.';
    END IF;
  END IF;

  -- Code is required
  IF (LENGTH(COALESCE(NEW.warehous_code,''))=0) THEN
    RAISE EXCEPTION 'You must supply a valid Site Code.';
  END IF;
  
  -- Sitetype is required
  IF (NEW.warehous_sitetype_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Site Type.';
  END IF;

  -- GL Account is required
  IF (NEW.warehous_default_accnt_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Default GL Account.';
  END IF;

  -- Cost Category is required for Transit types
  IF ((NEW.warehous_transit) AND (NEW.warehous_costcat_id IS NULL)) THEN
    RAISE EXCEPTION 'You must supply a valid Cost Category for Transit Sites.';
  END IF;

  -- Code must be unique
  SELECT warehous_id INTO _checkId
  FROM whsinfo
  WHERE ( (UPPER(warehous_code)=UPPER(NEW.warehous_code))
    AND   (warehous_id<>NEW.warehous_id) );
  IF (FOUND) THEN
    RAISE EXCEPTION 'You must supply a unique Site Code.';
  END IF;
  
  -- Count Tag Prefix must be unique
  IF (TG_OP = 'INSERT') THEN
    SELECT warehous_id INTO _checkId
    FROM whsinfo
    WHERE (warehous_counttag_prefix=NEW.warehous_counttag_prefix);
  ELSE
    SELECT warehous_id INTO _checkId
    FROM whsinfo
    WHERE ( (warehous_counttag_prefix=NEW.warehous_counttag_prefix)
      AND   (warehous_id<>NEW.warehous_id) );
  END IF;
  IF (FOUND) THEN
    RAISE EXCEPTION 'You must supply a unique Count Tag Prefix.';
  END IF;
  
  -- Check Complete
  -- Change Log
  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='WarehouseChangeLog') ) THEN

--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
    IF (FOUND) THEN
      IF (TG_OP = 'INSERT') THEN
        PERFORM postComment(_cmnttypeid, 'WH', NEW.warehous_id, 'Created');

      ELSIF (TG_OP = 'UPDATE') THEN
        IF (OLD.warehous_code <> NEW.warehous_code) THEN
          PERFORM postComment( _cmnttypeid, 'WH', NEW.warehous_id,
                               ('Code Changed from "' || OLD.warehous_code || '" to "' || NEW.warehous_code || '"') );
        END IF;

        IF (OLD.warehous_descrip <> NEW.warehous_descrip) THEN
          PERFORM postComment( _cmnttypeid, 'WH', NEW.warehous_id,
                               ( 'Description Changed from "' || OLD.warehous_descrip ||
                                 '" to "' || NEW.warehous_descrip || '"' ) );
        END IF;

        IF (OLD.warehous_active <> NEW.warehous_active) THEN
          IF (NEW.warehous_active) THEN
            PERFORM postComment(_cmnttypeid, 'WH', NEW.warehous_id, 'Activated');
          ELSE
            PERFORM postComment(_cmnttypeid, 'WH', NEW.warehous_id, 'Deactivated');
          END IF;
        END IF;

      END IF;
    END IF;
  END IF;
  
  RETURN NEW;

END;

Function: public._whsezonetrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check      BOOLEAN;
  _checkId    INTEGER;

BEGIN

  -- Checks
  -- Start with privileges
  IF (TG_OP = 'INSERT') THEN
    SELECT checkPrivilege('MaintainWarehouses') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to add new Site Zones.';
    END IF;
  ELSE
    SELECT checkPrivilege('MaintainWarehouses') INTO _check;
    IF NOT (_check) THEN
      RAISE EXCEPTION 'You do not have privileges to alter a Site Zone.';
    END IF;
  END IF;

  -- Name is required
  IF (LENGTH(COALESCE(NEW.whsezone_name,''))=0) THEN
    RAISE EXCEPTION 'You must supply a valid Site Zone Name.';
  END IF;
  
  -- Site is required
  IF (NEW.whsezone_warehous_id IS NULL) THEN
    RAISE EXCEPTION 'You must supply a valid Site.';
  END IF;

  RETURN NEW;

END;

Function: public._womatlaftertrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  IF (TG_OP = 'INSERT') THEN

  --  Create any required P/R's
    PERFORM createPr('W', NEW.womatl_id)
       FROM itemsite 
      WHERE ((itemsite_id=NEW.womatl_itemsite_id)
        AND  (itemsite_createpr));

  END IF;

  RETURN NEW;

END;

Function: public._wotrigger()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN

  IF ( SELECT (metric_value='t')
       FROM metric
       WHERE (metric_name='WorkOrderChangeLog') ) THEN
--  Cache the cmnttype_id for ChangeLog
    SELECT cmnttype_id INTO _cmnttypeid
    FROM cmnttype
    WHERE (cmnttype_name='ChangeLog');
  ELSE
    _cmnttypeid := -1;
  END IF;

  IF (TG_OP = 'INSERT') THEN
    INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'W', NEW.wo_id, itemsite_warehous_id, (NEW.wo_number || '-' || NEW.wo_subnumber) 
    FROM evntnot, evnttype, itemsite, item
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (itemsite_id=NEW.wo_itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (NEW.wo_duedate <= (CURRENT_DATE + itemsite_eventfence))
     AND (evnttype_name='WoCreated') );

     IF (_cmnttypeid <> -1) THEN
       PERFORM postComment(_cmnttypeid, 'W', NEW.wo_id, 'Created');
     END IF;

     IF (fetchMetricText('WONumberGeneration') IN ('A','O')) THEN
       --- clear the number from the issue cache
       PERFORM clearNumberIssue('WoNumber', NEW.wo_number);
     END IF;

     RETURN NEW;

  ELSE
    IF (TG_OP = 'DELETE') THEN
      INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                            evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number )
      SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
             'W', OLD.wo_id, itemsite_warehous_id, (OLD.wo_number || '-' || OLD.wo_subnumber) 
      FROM evntnot, evnttype, itemsite, item
      WHERE ( (evntnot_evnttype_id=evnttype_id)
       AND (evntnot_warehous_id=itemsite_warehous_id)
       AND (itemsite_id=OLD.wo_itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (OLD.wo_duedate <= (CURRENT_DATE + itemsite_eventfence))
       AND (evnttype_name='WoCancelled') );

      DELETE FROM comment
      WHERE ( (comment_source='W')
       AND (comment_source_id=OLD.wo_id) );

      DELETE FROM charass
       WHERE ((charass_target_type='W')
         AND  (charass_target_id=OLD.wo_id));

       RETURN OLD;

    ELSE
      IF (TG_OP = 'UPDATE') THEN

        IF (NEW.wo_qtyord <> OLD.wo_qtyord) THEN
          INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                                evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                                evntlog_oldvalue, evntlog_newvalue )
          SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
                 'W', NEW.wo_id, itemsite_warehous_id, (NEW.wo_number || '-' || NEW.wo_subnumber),
                 OLD.wo_qtyord, NEW.wo_qtyord
          FROM evntnot, evnttype, itemsite, item
          WHERE ( (evntnot_evnttype_id=evnttype_id)
           AND (evntnot_warehous_id=itemsite_warehous_id)
           AND (itemsite_id=NEW.wo_itemsite_id)
           AND (itemsite_item_id=item_id)
           AND ( (NEW.wo_duedate <= (CURRENT_DATE + itemsite_eventfence))
            OR   (OLD.wo_duedate <= (CURRENT_DATE + itemsite_eventfence)) )
           AND (evnttype_name='WoQtyChanged') );

          IF (_cmnttypeid <> -1) THEN
            PERFORM postComment( _cmnttypeid, 'W', NEW.wo_id,
                                 ( 'Qty. Ordered Changed from ' || formatQty(OLD.wo_qtyord) ||
                                   ' to ' || formatQty(NEW.wo_qtyord ) ) );
          END IF;
        END IF;

        IF (NEW.wo_duedate <> OLD.wo_duedate) THEN
          INSERT INTO evntlog ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                                evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                                evntlog_olddate, evntlog_newdate )
          SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
                 'W', NEW.wo_id, itemsite_warehous_id, (NEW.wo_number || '-' || NEW.wo_subnumber),
                 OLD.wo_duedate, NEW.wo_duedate
          FROM evntnot, evnttype, itemsite, item
          WHERE ( (evntnot_evnttype_id=evnttype_id)
           AND (evntnot_warehous_id=itemsite_warehous_id)
           AND (itemsite_id=NEW.wo_itemsite_id)
           AND (itemsite_item_id=item_id)
           AND ( (NEW.wo_duedate <= (CURRENT_DATE + itemsite_eventfence))
            OR   (OLD.wo_duedate <= (CURRENT_DATE + itemsite_eventfence)) )
           AND (evnttype_name='WoDueDateChanged') );

          IF (_cmnttypeid <> -1) THEN
            PERFORM postComment( _cmnttypeid, 'W', NEW.wo_id,
                                 ( 'Due Date Changed from ' || formatDate(OLD.wo_duedate) ||
                                   ' to ' || formatDate(NEW.wo_duedate ) ) );
          END IF;
        END IF;

        IF (NEW.wo_status <> OLD.wo_status) THEN
          IF (_cmnttypeid <> -1) THEN
            PERFORM postComment( _cmnttypeid, 'W', NEW.wo_id,
                                 ('Status Changed from ' || OLD.wo_status || ' to ' || NEW.wo_status) );
          END IF;
        END IF;

      END IF; 
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public.acknowledgemessage(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMsgid ALIAS FOR $1;

BEGIN

  UPDATE msguser
  SET msguser_viewed=CURRENT_TIMESTAMP
  WHERE ( (msguser_msg_id=pMsgid)
   AND (msguser_username=getEffectiveXtUser()) );

  RETURN TRUE;

END;

Function: public.actcost(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN actCost($1, NULL, baseCurrId());
END;

Function: public.actcost(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN actCost($1, $2, baseCurrId());
END;

Function: public.actcost(integer, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pBomitemid ALIAS FOR $2;
  pCurrid ALIAS FOR $3;
  _cost NUMERIC;

BEGIN

  -- Return actual cost in the given currency at the current conversion rate
  SELECT SUM(CASE WHEN (bomitemcost_id IS NOT NULL) THEN
                  ROUND(currToCurr(bomitemcost_curr_id, pCurrid, bomitemcost_actcost, CURRENT_DATE), 6)
                  ELSE
                  ROUND(currToCurr(itemcost_curr_id, pCurrid, itemcost_actcost, CURRENT_DATE), 6)
             END) INTO _cost
  FROM itemcost
    LEFT OUTER JOIN bomitemcost ON (bomitemcost_bomitem_id=pBomitemid AND bomitemcost_costelem_id=itemcost_costelem_id)
  WHERE (itemcost_item_id=pItemid);

  IF (_cost IS NULL) THEN
    RETURN 0;
  ELSE
    RETURN _cost;
  END IF;

END;

Function: public.addrusecount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAddrId ALIAS FOR $1;
  _fk RECORD;
  _r RECORD;
  _seq INTEGER;
  _col TEXT;
  _qry TEXT;
  _count INTEGER = 0;

BEGIN
  -- Determine where this address is used by analyzing foreign key linkages
  -- TO DO: Can this be rationalized with cntctused(int)?
  FOR _fk IN
    SELECT pg_namespace.nspname AS schemaname, con.relname AS tablename, conkey AS seq, conrelid AS class_id 
    FROM pg_constraint, pg_class f, pg_class con, pg_namespace
    WHERE confrelid=f.oid
    AND conrelid=con.oid
    AND f.relname = 'addr'
    AND con.relnamespace=pg_namespace.oid
    AND con.relname NOT IN ('pohead') -- exception(s) where address key doesn't actually drive document information
  LOOP
    -- Validate
    IF (ARRAY_UPPER(_fk.seq,1) > 1) THEN
      RAISE EXCEPTION 'Checks to tables where the address is one of multiple foreign key columns is not supported. Error on Table: %',
        pg_namespace.nspname || '.' || con.relname;
    END IF;
    
    _seq := _fk.seq[1];

    -- Get the specific column name
    SELECT attname INTO _col
    FROM pg_attribute, pg_class
    WHERE ((attrelid=pg_class.oid)
    AND (pg_class.oid=_fk.class_id)
    AND (attnum=_seq));

    -- See if there are dependencies
    _qry := 'SELECT * 
            FROM ' || _fk.schemaname || '.' || _fk.tablename || '
            WHERE ('|| _col || '=' || pAddrId || ');';

    FOR _r IN 
      EXECUTE _qry
    LOOP
      _count := _count + 1;
    END LOOP;
         
  END LOOP;

  RETURN _count;

END;

Function: public.addtaxtoglseries(integer, text, text, text, integer, date, date, text, integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence	ALIAS FOR $1;
  pSource	ALIAS FOR $2;
  pDocType	ALIAS FOR $3;
  pDocNumber	ALIAS FOR $4;
  pCurrId     ALIAS FOR $5;
  pExchDate	ALIAS FOR $6;
  pDistDate	ALIAS FOR $7;
  pTableName	ALIAS FOR $8;
  pParentId	ALIAS FOR $9;
  pNotes	ALIAS FOR $10;

  _count	INTEGER := 0;
  _baseTax	NUMERIC := 0;
  _returnVal	NUMERIC := 0;
  _t		RECORD;
  _test	INTEGER := 0;

BEGIN

-- This is just a fancy select statement on taxhist.
-- Because all tax records tables inherit from taxhist,
-- we can use the same select statement for all.
-- https://www.postgresql.org/docs/8.1/static/ddl-inherit.html
-- pTableName in the where clause narrows down the selection
-- to the correct sub table.

  FOR _t IN SELECT *
            FROM taxhist JOIN tax ON (tax_id = taxhist_tax_id)
                         JOIN pg_class ON (pg_class.oid = taxhist.tableoid)
            WHERE ( (taxhist_parent_id = pParentId)
              AND   (relname = pTableName) ) LOOP

    _count := _count + 1;
    _baseTax := currToBase(pCurrId, _t.taxhist_tax, pExchDate);
    _returnVal := _returnVal + _baseTax;
    PERFORM insertIntoGLSeries( pSequence, pSource, pDocType, pDocNumber,
                                _t.tax_sales_accnt_id, _baseTax,
                                pDistDate, pNotes );
                                
    UPDATE taxhist SET 
      taxhist_docdate=pExchDate,
      taxhist_distdate=pDistDate,
      taxhist_curr_id=pCurrId,
      taxhist_curr_rate=curr_rate
    FROM curr_rate
    WHERE ((taxhist_id=_t.taxhist_id)
      AND (pCurrId=curr_id)
      AND ( pExchDate BETWEEN curr_effective 
                          AND curr_expires) );

  END LOOP;

  RETURN _returnVal;
END;

Function: public.addtopackinglistbatch(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid	ALIAS FOR $1;
  returnVal	INTEGER;
BEGIN

  -- MIN because error codes are negative
  SELECT MIN(addToPackingListBatch('SO', pSoheadid, shiphead_id)) INTO returnVal
  FROM shiphead
  WHERE ((shiphead_order_id=pSoheadid)
    AND  (NOT shiphead_shipped)
    AND  (shiphead_order_type='SO'));
  IF (NOT FOUND OR returnVal IS NULL) THEN
    returnVal := addToPackingListBatch('SO', pSoheadid, NULL);
  END IF;

  RETURN returnVal;
END;

Function: public.addtopackinglistbatch(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN addToPackingListBatch('SO', $1, $2);
END;

Function: public.addtopackinglistbatch(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pheadtype	ALIAS FOR $1;
  pheadid	ALIAS FOR $2;
  returnVal	INTEGER;
BEGIN
  -- MIN because error codes are negative
  SELECT MIN(addToPackingListBatch(pheadtype, pheadid, shiphead_id)) INTO returnVal
  FROM shiphead
  WHERE ((shiphead_order_id=pheadid)
    AND  (NOT shiphead_shipped)
    AND  (shiphead_order_type=pheadtype));

  IF (NOT FOUND OR returnVal IS NULL) THEN
    returnVal := addToPackingListBatch(pheadtype, pheadid, NULL);
  END IF;

  RETURN returnVal;
END;

Function: public.addtopackinglistbatch(text, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pheadtype	ALIAS FOR $1;
  pheadid	ALIAS FOR $2;
  pshipheadid	ALIAS FOR $3;
  _check INTEGER;

BEGIN
  SELECT pack_id INTO _check
  FROM pack
  WHERE ((pack_head_id=pheadid)
    AND  ((pack_shiphead_id=pshipheadid) OR 
	  (pshipheadid IS NULL AND pack_shiphead_id IS NULL))
    AND  (pack_head_type=pheadtype)
	);

  IF (NOT FOUND) THEN
    INSERT INTO pack
    ( pack_head_type, pack_head_id, pack_shiphead_id, pack_printed )
    VALUES
    ( pheadtype, pheadid, pshipheadid, FALSE );
    -- Auto Firm Sales Orders conditionally based on metric
    IF ( (pheadtype = 'SO') AND (fetchMetricBool('FirmSalesOrderPackingList')) ) THEN
      UPDATE coitem SET coitem_firm=TRUE
      WHERE (coitem_cohead_id=pheadid);
    END IF; 
  END IF;

  RETURN pheadid;

END;

Function: public.adjustinvvalue(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid     ALIAS FOR $1;
  pNewValue       ALIAS FOR $2;
  pAccountid      ALIAS FOR $3;
  _delta          NUMERIC;
  _glreturn       INTEGER;
  _invhistid      INTEGER;
  _itemlocSeries  INTEGER;

BEGIN

  SELECT pNewValue - itemsite_value INTO _delta
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid)
  FOR UPDATE;

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT insertGLTransaction('I/M', '', 'Post Value',
         'Inventory Value Adjustment for ' || item_number,
         COALESCE (pAccountid, costcat_adjustment_accnt_id),
         costcat_asset_accnt_id, -1,
         _delta, CURRENT_DATE) INTO _glreturn
  FROM itemsite
   JOIN costcat ON (itemsite_costcat_id=costcat_id)
   JOIN item ON (itemsite_item_id=item_id)
  WHERE (itemsite_id=pItemsiteid);

--  Create the AD transaction
  INSERT INTO invhist
   ( invhist_itemsite_id,
     invhist_transdate, invhist_transtype, invhist_invqty,
     invhist_qoh_before, invhist_qoh_after,
     invhist_docnumber, invhist_comments,
     invhist_invuom, invhist_unitcost, invhist_hasdetail,
     invhist_costmethod, invhist_value_before, invhist_value_after,
     invhist_series )
  SELECT itemsite_id,
         CURRENT_TIMESTAMP, 'AD', 0.0,
         itemsite_qtyonhand, itemsite_qtyonhand,
         '', 'Inventory Value Adjustment',
         uom_name, _delta, FALSE,
         itemsite_costmethod, itemsite_value, pNewValue,
         0
  FROM itemsite, item, uom
  WHERE ( (itemsite_item_id=item_id)
   AND (item_inv_uom_id=uom_id)
   AND (itemsite_id=pItemsiteid) );

  UPDATE itemsite SET itemsite_value=pNewValue
  WHERE (itemsite_id=pItemsiteid);

  RETURN 0;

END;

Function: public.adjustments(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;

BEGIN
  IF (pTransType IN ('CC', 'AD')) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.allocatedforso(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN allocatedForSo(pItemsiteid, startOfTime(), pDate);

END;

Function: public.allocatedforso(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _qty NUMERIC;

BEGIN

  SELECT COALESCE(SUM(noNeg(itemuomtouom(itemsite_item_id, coitem_qty_uom_id, NULL, coitem_qtyord - (coitem_qtyshipped + qtyAtShipping(coitem_id)) + coitem_qtyreturned))), 0.0) INTO _qty
  FROM coitem, itemsite, item
  WHERE ( (coitem_itemsite_id=itemsite_id)
    AND (itemsite_item_id=item_id)
    AND (coitem_status='O')
    AND (coitem_itemsite_id=pItemsiteid)
    AND (coitem_scheddate BETWEEN pStartDate AND pEndDate) );

  RETURN _qty;

END;

Function: public.allocatedforso(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN allocatedForSo(pItemsiteid, startOfTime(), (CURRENT_DATE + pDate));

END;

Function: public.allocatedforwo(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN allocatedForWo(pItemsiteid, startOfTime(), pDate);

END;

Function: public.allocatedforwo(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _qty NUMERIC;

BEGIN

  SELECT
    CASE WHEN (item_type != 'T') THEN
      COALESCE(SUM(noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss))), 0.0)
    ELSE -- Special handling for tooling
      COALESCE(SUM(noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq))), 0.0)  -
	(
		SELECT COALESCE(SUM(invhist_invqty),0) 
		FROM itemsite, item, wo, womatl
			LEFT OUTER JOIN womatlpost ON (womatl_id=womatlpost_womatl_id)
			LEFT OUTER JOIN invhist ON ((womatlpost_invhist_id=invhist_id)
                            AND (invhist_invqty > 0))
		WHERE ( (womatl_itemsite_id=pItemsiteid)
		AND (womatl_itemsite_id=itemsite_id)
		AND (itemsite_item_id=item_id)
		AND (womatl_duedate BETWEEN pStartDate AND pEndDate) 
		AND (wo_id=womatl_wo_id)
		AND (wo_status IN ('E','I','R')) )
	) 
    END INTO _qty
  FROM wo, womatl, itemsite, item
  WHERE ( (womatl_itemsite_id=pItemsiteid)
   AND (womatl_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (womatl_duedate BETWEEN pStartDate AND pEndDate) 
   AND (wo_id=womatl_wo_id)
   AND (wo_status IN ('E','I','R')) )
  GROUP BY item_type;

  RETURN COALESCE(_qty,0);

END;

Function: public.allocatedforwo(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAheadDays ALIAS FOR $2;

BEGIN

  RETURN allocatedForWo(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookaheadDays));

END;

Function: public.alterencrypt(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOldKey ALIAS FOR $1;
  pNewKey ALIAS FOR $2;
  _cc RECORD;
  _ccaud RECORD;
  _metricenc RECORD;
  num_updated INTEGER;

BEGIN

  num_updated := 0;

-- Update ccard

  FOR _cc IN SELECT ccard_id, 
             decrypt(setbytea(ccard_name), setbytea(pOldKey), 'bf') AS ccard_name,
             decrypt(setbytea(ccard_address1), setbytea(pOldKey), 'bf') AS ccard_address1,
             decrypt(setbytea(ccard_address2), setbytea(pOldKey), 'bf') AS ccard_address2,
             decrypt(setbytea(ccard_city), setbytea(pOldKey), 'bf') AS ccard_city,
             decrypt(setbytea(ccard_state), setbytea(pOldKey), 'bf') AS ccard_state,
             decrypt(setbytea(ccard_zip), setbytea(pOldKey), 'bf') AS ccard_zip,
             decrypt(setbytea(ccard_country), setbytea(pOldKey), 'bf') AS ccard_country,
             decrypt(setbytea(ccard_number), setbytea(pOldKey), 'bf') AS ccard_number,
             decrypt(setbytea(ccard_month_expired), setbytea(pOldKey), 'bf') AS ccard_month_expired,
             decrypt(setbytea(ccard_year_expired), setbytea(pOldKey), 'bf') AS ccard_year_expired
      FROM ccard LOOP

      UPDATE ccard
             set ccard_name = encrypt(setbytea(_cc.ccard_name), setbytea(pNewKey), 'bf'),
                 ccard_address1 = encrypt(setbytea(_cc.ccard_address1), setbytea(pNewKey), 'bf'),
                 ccard_address2 = encrypt(setbytea(_cc.ccard_address2), setbytea(pNewKey), 'bf'),
                 ccard_city = encrypt(setbytea(_cc.ccard_city), setbytea(pNewKey), 'bf'),
                 ccard_state = encrypt(setbytea(_cc.ccard_state), setbytea(pNewKey), 'bf'),
                 ccard_zip = encrypt(setbytea(_cc.ccard_zip), setbytea(pNewKey), 'bf'),
                 ccard_country = encrypt(setbytea(_cc.ccard_country), setbytea(pNewKey), 'bf'),
                 ccard_number = encrypt(setbytea(_cc.ccard_number), setbytea(pNewKey), 'bf'),
                 ccard_month_expired = encrypt(setbytea(_cc.ccard_month_expired), setbytea(pNewKey), 'bf'),
                 ccard_year_expired = encrypt(setbytea(_cc.ccard_year_expired), setbytea(pNewKey), 'bf')
      WHERE ccard_id = _cc.ccard_id;

      num_updated := num_updated + 1;

  END LOOP;

-- Update ccardaud

  FOR _ccaud IN SELECT ccardaud_id, 
             decrypt(setbytea(ccardaud_ccard_name_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_name_old,
             decrypt(setbytea(ccardaud_ccard_name_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_name_new,
             decrypt(setbytea(ccardaud_ccard_address1_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_address1_old,
             decrypt(setbytea(ccardaud_ccard_address1_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_address1_new,
             decrypt(setbytea(ccardaud_ccard_address2_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_address2_old,
             decrypt(setbytea(ccardaud_ccard_address2_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_address2_new,
             decrypt(setbytea(ccardaud_ccard_city_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_city_old,
             decrypt(setbytea(ccardaud_ccard_city_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_city_new,
             decrypt(setbytea(ccardaud_ccard_state_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_state_old,
             decrypt(setbytea(ccardaud_ccard_state_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_state_new,
             decrypt(setbytea(ccardaud_ccard_zip_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_zip_old,
             decrypt(setbytea(ccardaud_ccard_zip_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_zip_new,
             decrypt(setbytea(ccardaud_ccard_country_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_country_old,
             decrypt(setbytea(ccardaud_ccard_country_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_country_new,
             decrypt(setbytea(ccardaud_ccard_number_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_number_old,
             decrypt(setbytea(ccardaud_ccard_number_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_number_new,
             decrypt(setbytea(ccardaud_ccard_month_expired_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_month_expired_old,
             decrypt(setbytea(ccardaud_ccard_month_expired_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_month_expired_new,
             decrypt(setbytea(ccardaud_ccard_year_expired_old), setbytea(pOldKey), 'bf') AS ccardaud_ccard_year_expired_old,
             decrypt(setbytea(ccardaud_ccard_year_expired_new), setbytea(pOldKey), 'bf') AS ccardaud_ccard_year_expired_new
      FROM ccardaud LOOP

      UPDATE ccardaud
             set ccardaud_ccard_name_old = encrypt(setbytea(_ccaud.ccardaud_ccard_name_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_name_new = encrypt(setbytea(_ccaud.ccardaud_ccard_name_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_address1_old = encrypt(setbytea(_ccaud.ccardaud_ccard_address1_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_address1_new = encrypt(setbytea(_ccaud.ccardaud_ccard_address1_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_address2_old = encrypt(setbytea(_ccaud.ccardaud_ccard_address2_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_address2_new = encrypt(setbytea(_ccaud.ccardaud_ccard_address2_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_city_old = encrypt(setbytea(_ccaud.ccardaud_ccard_city_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_city_new = encrypt(setbytea(_ccaud.ccardaud_ccard_city_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_state_old = encrypt(setbytea(_ccaud.ccardaud_ccard_state_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_state_new = encrypt(setbytea(_ccaud.ccardaud_ccard_state_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_zip_old = encrypt(setbytea(_ccaud.ccardaud_ccard_zip_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_zip_new = encrypt(setbytea(_ccaud.ccardaud_ccard_zip_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_country_old = encrypt(setbytea(_ccaud.ccardaud_ccard_country_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_country_new = encrypt(setbytea(_ccaud.ccardaud_ccard_country_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_number_old = encrypt(setbytea(_ccaud.ccardaud_ccard_number_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_number_new = encrypt(setbytea(_ccaud.ccardaud_ccard_number_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_month_expired_old = encrypt(setbytea(_ccaud.ccardaud_ccard_month_expired_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_month_expired_new = encrypt(setbytea(_ccaud.ccardaud_ccard_month_expired_new), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_year_expired_old = encrypt(setbytea(_ccaud.ccardaud_ccard_year_expired_old), setbytea(pNewKey), 'bf'),
                 ccardaud_ccard_year_expired_new = encrypt(setbytea(_ccaud.ccardaud_ccard_year_expired_new), setbytea(pNewKey), 'bf')
      WHERE ccardaud_id = _ccaud.ccardaud_id;

      num_updated := num_updated + 1;

  END LOOP;

-- Update metricenc

  FOR _metricenc IN SELECT metricenc_id, 
             decrypt(setbytea(metricenc_value), setbytea(pOldKey), 'bf') AS metricenc_value
      FROM metricenc LOOP

      UPDATE metricenc
             set metricenc_value = encrypt(setbytea(_metricenc.metricenc_value), setbytea(pNewKey), 'bf')
      WHERE metricenc_id = _metricenc.metricenc_id;

      num_updated := num_updated + 1;

  END LOOP;


  RETURN num_updated;

END;

Function: public.apaging(date, boolean)

Returns: SET OF apaging

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAsOfDate ALIAS FOR $1;
  pUseDocDate ALIAS FOR $2;
  _row apaging%ROWTYPE;
  _x RECORD;
  _returnVal INTEGER;
  _asOfDate DATE;
BEGIN

  _asOfDate := COALESCE(pAsOfDate,current_date);

  FOR _x IN
        SELECT
        --report uses currency rate snapshot to convert all amounts to base based on apopen_docdate to ensure the same exchange rate

        --today and greater base:
        CASE WHEN((apopen_duedate >= DATE(_asOfDate)))
        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS cur_val,

        --0 to 30 base
        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-30) AND (apopen_duedate < DATE(_asOfDate)))
        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS thirty_val,

        --30-60 base
        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-60) AND (apopen_duedate < DATE(_asOfDate) - 30 ))
        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS sixty_val,

        --60-90 base
        CASE WHEN((apopen_duedate >= DATE(_asOfDate)-90) AND (apopen_duedate < DATE(_asOfDate) - 60))
        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS ninety_val,

        --greater than 90 base:
        CASE WHEN((apopen_duedate > DATE(_asOfDate)-10000) AND (apopen_duedate < DATE(_asOfDate) - 90))
        THEN (((apopen_amount-apopen_paid + COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS plus_val,

        --total amount base:
        CASE WHEN((apopen_duedate > DATE(_asOfDate)-10000))
        THEN (((apopen_amount-apopen_paid+COALESCE(SUM(apapply_target_paid),0)))/apopen_curr_rate *
        CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END) ELSE 0 END AS total_val,

        --AP Open Amount base
        CASE WHEN apopen_doctype IN ('C', 'R') 
        THEN (apopen_amount * -1) / apopen_curr_rate
        ELSE apopen_amount / apopen_curr_rate END AS apopen_amount,
        
        apopen_docdate,
        apopen_duedate,
        apopen_ponumber,
        apopen_invcnumber,
        apopen_docnumber,
        apopen_doctype,
        vend_id,
        vend_name,
        vend_number,
        vend_vendtype_id,
        vendtype_code,
        terms_descrip,
        determineDiscountDate(terms_id, apopen_docdate) AS discdate,
        noNeg(apopen_discountable_amount *
                     CASE WHEN (CURRENT_DATE <= determineDiscountDate(terms_id, apopen_docdate)) THEN terms_discprcnt
                     ELSE 0.0 END) AS disc_val,
        terms_discdays AS discdays,
        (terms_discprcnt * 100.0) AS discprcnt

        FROM vendinfo, vendtype, apopen
          LEFT OUTER JOIN terms ON (apopen_terms_id=terms_id)
          LEFT OUTER JOIN apapply ON (((apopen_id=apapply_target_apopen_id)
                                    OR (apopen_id=apapply_source_apopen_id))
                                   AND (apapply_postdate >_asOfDate))
        WHERE ( (apopen_vend_id = vend_id)
        AND (vend_vendtype_id=vendtype_id)
        AND (CASE WHEN (pUseDocDate) THEN apopen_docdate ELSE apopen_distdate END <= _asOfDate)
        AND (COALESCE(apopen_closedate,_asOfDate+1)>_asOfDate) )
        GROUP BY apopen_id,apopen_docdate,apopen_duedate,apopen_ponumber, apopen_invcnumber, apopen_docnumber,apopen_doctype,apopen_paid,
                 apopen_curr_id,apopen_amount,vend_id,vend_name,vend_number,vend_vendtype_id,vendtype_code,terms_descrip,
                 apopen_curr_rate, terms_id, terms_discdays, terms_discprcnt, apopen_discountable_amount
        ORDER BY vend_number, apopen_duedate
  LOOP
        _row.apaging_docdate := _x.apopen_docdate;
        _row.apaging_duedate := _x.apopen_duedate;
        _row.apaging_ponumber := _x.apopen_ponumber;
        _row.apaging_invcnumber := _x.apopen_invcnumber;
        _row.apaging_docnumber := _x.apopen_docnumber;
        _row.apaging_doctype := _x.apopen_doctype;
        _row.apaging_vend_id := _x.vend_id;
        _row.apaging_vend_number := _x.vend_number;
        _row.apaging_vend_name := _x.vend_name;
        _row.apaging_vend_vendtype_id := _x.vend_vendtype_id;
        _row.apaging_vendtype_code := _x.vendtype_code;
        _row.apaging_terms_descrip := _x.terms_descrip;
        _row.apaging_apopen_amount := _x.apopen_amount;
        _row.apaging_cur_val := _x.cur_val;
        _row.apaging_thirty_val := _x.thirty_val;
        _row.apaging_sixty_val := _x.sixty_val;
        _row.apaging_ninety_val := _x.ninety_val;
        _row.apaging_plus_val := _x.plus_val;
        _row.apaging_total_val := _x.total_val;
        _row.apaging_discdate := _x.discdate;
        _row.apaging_disc_val := _x.disc_val;
        _row.apaging_discdays := _x.discdays;
        _row.apaging_discprcnt := _x.discprcnt;
        RETURN NEXT _row;
  END LOOP;
  RETURN;
END;

Function: public.apapplied(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  _amount NUMERIC;

BEGIN

  -- Return amount applied to an apopen in base currency as of apapply_postdate
  SELECT SUM(currtobase(apapply_curr_id,apapply_amount,apapply_postdate)) INTO _amount
  FROM apapply
  WHERE (((apapply_target_apopen_id = pApopenid) OR (apapply_source_apopen_id = pApopenid))
  AND (((apapply_journalnumber=0) AND (apapply_postdate <= pDate))
  OR EXISTS(SELECT * 
             FROM gltrans 
             WHERE ((gltrans_journalnumber=apapply_journalnumber)
             AND (gltrans_date <= pDate)))));

  IF (_amount IS NULL) THEN
    RETURN 0;
  ELSE
    RETURN _amount;
  END IF;

END;

Function: public.apcheckpending(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid	ALIAS FOR $1;
  _qty NUMERIC  := 0.0;

BEGIN

  SELECT SUM(checkitem_amount + checkitem_discount) INTO _qty
    FROM checkitem JOIN checkhead ON (checkitem_checkhead_id=checkhead_id)
   WHERE ((checkitem_apopen_id=pApopenid)
     AND (NOT checkhead_deleted)
     AND (NOT checkhead_replaced)
     AND (NOT checkhead_posted));

  RETURN COALESCE(_qty, 0.0);

END;

Function: public.apcurrgain(integer, integer, numeric, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenId ALIAS FOR $1;
  pCurrId ALIAS FOR $2;
  pValue ALIAS FOR $3;
  pDate ALIAS FOR $4;
  _start DATE;
  _end DATE;
  _gain NUMERIC;
  _r RECORD;

BEGIN
  IF (pApopenId IS NULL OR pValue = 0) THEN
    RETURN 0;
  END IF;

  SELECT apopen_docdate, apopen_curr_rate
    INTO _r
  FROM apopen
  WHERE (apopen_id=pApopenId);

  IF (_r.apopen_docdate > pDate) THEN
    _gain := (currToBase(pCurrId, pValue, pDate) - (pValue / _r.apopen_curr_rate)) * -1;
  ELSE
    _gain := (pValue / _r.apopen_curr_rate) - currToBase(pCurrId, pValue, pDate);
  END IF;
  
  IF (_gain IS NULL) THEN
    RAISE EXCEPTION 'Error processing currency gain/loss.';
  END IF;

  RETURN _gain;
END;

Function: public.applyapcreditmemotobalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  _amount NUMERIC;
  _curr_id INTEGER;
  _curr_rate NUMERIC;
  _docdate DATE;
  _applyAmount NUMERIC;
  _r RECORD;
  _p RECORD;

BEGIN

--  Find the balance to apply
  SELECT (apopen_amount - apopen_paid - COALESCE(prepared,0.0) - COALESCE(selected,0.0) - COALESCE(SUM(currToCurr(apcreditapply_curr_id,
                                                  apopen_curr_id,
                                                  apcreditapply_amount,
                                                  apopen_docdate)), 0)),
          apopen_curr_id, apopen_curr_rate, apopen_docdate INTO _amount, _curr_id, _curr_rate, _docdate
  FROM apopen 
    LEFT OUTER JOIN apcreditapply ON (apcreditapply_source_apopen_id=apopen_id)
    LEFT OUTER JOIN (SELECT apopen_id AS selected_apopen_id,
                       SUM(currToCurr(apselect_curr_id, apopen_curr_id, apselect_amount + apselect_discount, apselect_date)) AS selected
                     FROM apselect JOIN apopen ON (apselect_apopen_id=apopen_id)
                     GROUP BY apopen_id) AS sub1 ON (apopen_id=selected_apopen_id)
    LEFT OUTER JOIN (SELECT apopen_id AS prepared_apopen_id,
                       SUM(checkitem_amount + checkitem_discount) AS prepared
                     FROM checkhead 
                       JOIN checkitem ON (checkitem_checkhead_id=checkhead_id)
                       JOIN apopen ON (checkitem_apopen_id=apopen_id)
                     WHERE ((NOT checkhead_posted)
                       AND  (NOT checkhead_void))
                     GROUP BY apopen_id) AS sub2 ON (prepared_apopen_id=apopen_id)
  WHERE (apopen_id=pApopenid)
  GROUP BY apopen_amount, apopen_paid, apopen_curr_id, apopen_curr_rate, apopen_docdate, prepared, selected;

  IF (_amount < 0) THEN
    RETURN -1;
  END IF;

--  Loop through the apopen items in order of due date
  FOR _r IN SELECT target.apopen_id AS apopenid,
                   currToCurr(target.apopen_curr_id,source.apopen_curr_id, 
                     target.apopen_amount - target.apopen_paid - COALESCE(prepared,0.0) - COALESCE(selected,0.0) - COALESCE(applied,0.0),
                     current_date) AS balance
           FROM apopen AS source, apopen AS target
             LEFT OUTER JOIN (SELECT apcreditapply_target_apopen_id AS applied_apopen_id,
                                     SUM(currToCurr(apcreditapply_curr_id, apopen_curr_id, apcreditapply_amount, apopen_docdate)) AS applied
                              FROM apcreditapply JOIN apopen ON (apopen_id=apcreditapply_source_apopen_id)
                              GROUP BY apcreditapply_target_apopen_id) AS sub3
                              ON (target.apopen_id=applied_apopen_id)
             LEFT OUTER JOIN (SELECT apopen_id AS selected_apopen_id,
                                SUM(currToCurr(apselect_curr_id, apopen_curr_id, apselect_amount + apselect_discount, apselect_date)) AS selected
                                    FROM apselect JOIN apopen ON (apselect_apopen_id=apopen_id)
                                GROUP BY apopen_id) AS sub1
                                ON (target.apopen_id=selected_apopen_id)
             LEFT OUTER JOIN (SELECT apopen_id AS prepared_apopen_id,
                                SUM(checkitem_amount + checkitem_discount) AS prepared
                              FROM checkhead 
                                JOIN checkitem ON (checkitem_checkhead_id=checkhead_id)
                                JOIN apopen ON (checkitem_apopen_id=apopen_id)
                              WHERE ((NOT checkhead_posted)
                               AND  (NOT checkhead_void))
                              GROUP BY apopen_id) AS sub2 ON (prepared_apopen_id=target.apopen_id)
            WHERE ( (source.apopen_vend_id=target.apopen_vend_id)
             AND (target.apopen_doctype IN ('V', 'D'))
             AND (target.apopen_open)
             AND (source.apopen_id=pApopenid) )
            ORDER BY target.apopen_duedate, (target.apopen_amount - target.apopen_paid) LOOP

--  Determine the amount to apply
    IF (_r.balance <= 0.0) THEN
      CONTINUE;
    ELSEIF (_r.balance > _amount) THEN
      _applyAmount := _amount;
    ELSE
      _applyAmount := _r.balance;
    END IF;

--  Does an apcreditapply record already exist?
    SELECT apcreditapply_id, 
              apcreditapply_amount * _curr_rate / 
                 currRate(apcreditapply_curr_id,_docdate) AS apcreditapply_amount
      INTO _p
    FROM apcreditapply
    WHERE ( (apcreditapply_target_apopen_id=_r.apopenid)
     AND (apcreditapply_source_apopen_id=pApopenid) );

    IF (FOUND) THEN
--  The following is depreciated, just skip the record
--  Recalculate the amount to apply
--      IF ((_r.balance - _p.apcreditapply_amount) > _amount) THEN
--        _applyAmount := _amount;
--      ELSE
--        _applyAmount := (_r.balance - _p.apcreditapply_amount);
--      END IF;

--  Update the apcreditapply with the new amount to apply
--      UPDATE apcreditapply
--      SET apcreditapply_amount = (apcreditapply_amount + 
--          _applyAmount *  currRate(apcreditapply_curr_id,_docdate) / _curr_rate)
--      WHERE (apcreditapply_id=_p.apcreditapply_id);

      CONTINUE;
    ELSE
--  Create a new apcreditapply record
      INSERT INTO apcreditapply
      ( apcreditapply_source_apopen_id, apcreditapply_target_apopen_id,
        apcreditapply_amount, apcreditapply_curr_id )
      VALUES
      ( pApopenid, _r.apopenid, _applyAmount, _curr_id );
    END IF;

    _amount := (_amount - _applyAmount);
    IF (_amount = 0) THEN
      EXIT;
    END IF;

  END LOOP;

  RETURN 1;

END;

Function: public.applyapcredits(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendId   ALIAS FOR $1;
  _result   INTEGER;
  _apopenid INTEGER;
  _r        RECORD;

BEGIN

  -- Fetch credit memo(s) for the vendor
  FOR _r IN SELECT apopen_id, apopen_duedate
            FROM apopen JOIN vendinfo ON (apopen_vend_id = vend_id)
            WHERE ((apopen_doctype = 'C')
               AND (apopen_status = 'O')
               AND (vend_id = pVendId))
            ORDER BY apopen_duedate
  LOOP
    -- Apply credit memo(s) according to due date
    SELECT applyapcreditmemotobalance(_r.apopen_id) INTO _result;

    -- Post the credit memo if applied
    IF (_result = 1) THEN
      SELECT postapcreditmemoapplication(_r.apopen_id) INTO _apopenid;
      IF (_apopenid < 0) THEN
        RETURN -1;
      END IF;
    ELSE
      RETURN -1;
    END IF;

  END LOOP;

RETURN 1;

END;

Function: public.applyarcreditmemotobalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAropenid ALIAS FOR $1;

BEGIN

  RETURN applyARCreditMemoToBalance(pAropenid, NULL);

END;

Function: public.applyarcreditmemotobalance(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceAropenid ALIAS FOR $1;
  pTargetAropenid ALIAS FOR $2;
  _amount NUMERIC;
  _amountcurrid INTEGER;
  _applyAmount NUMERIC;
  _applycurrid  INTEGER;
  _curr_rate NUMERIC;
  _r RECORD;
  _p RECORD;

BEGIN

--  Find the balance to apply
  SELECT (aropen_amount - COALESCE(SUM(currToCurr(arcreditapply_curr_id,
                                                  aropen_curr_id,
                                                  arcreditapply_amount,
                                                  aropen_docdate)), 0) - aropen_paid - COALESCE(prepared,0.0) - COALESCE(cashapplied,0.0)),
         aropen_curr_id, aropen_curr_rate INTO _amount, _amountcurrid, _curr_rate
  FROM aropen LEFT OUTER JOIN arcreditapply ON (arcreditapply_source_aropen_id=aropen_id)
	      LEFT OUTER JOIN (SELECT aropen_id AS prepared_aropen_id,
                                SUM(checkitem_amount + checkitem_discount) AS prepared
                               FROM checkhead JOIN checkitem ON (checkitem_checkhead_id=checkhead_id)
                                              JOIN aropen ON (checkitem_aropen_id=aropen_id)
                               WHERE ((NOT checkhead_posted)
                                AND  (NOT checkhead_void))
                               GROUP BY aropen_id) AS sub1
                      ON (prepared_aropen_id=aropen_id)
             LEFT OUTER JOIN (SELECT aropen_id AS cash_aropen_id,
                                     SUM(cashrcptitem_amount + cashrcptitem_discount) * -1.0 AS cashapplied
                                FROM cashrcpt JOIN cashrcptitem ON (cashrcptitem_cashrcpt_id=cashrcpt_id)
                                              JOIN aropen ON (cashrcptitem_aropen_id=aropen_id)
                               WHERE (NOT cashrcpt_posted) AND (NOT cashrcpt_void)
                               GROUP BY aropen_id ) AS sub2
                      ON (cash_aropen_id=aropen_id)
  WHERE (aropen_id=pSourceAropenid)
  GROUP BY aropen_amount, aropen_paid, aropen_curr_id, aropen_curr_rate, prepared, cashapplied;

  IF (_amount < 0) THEN
    RETURN -1;
  END IF;

--  Loop through the aropen items in order of due date
  FOR _r IN SELECT target.aropen_id AS aropenid,
                   currToCurr(target.aropen_curr_id,source.aropen_curr_id,
                              (target.aropen_amount - target.aropen_paid - calcpendingarapplications(target.aropen_id)),
                              current_date) AS balance,
                   target.aropen_curr_id AS curr_id,
                   target.aropen_docdate AS docdate
            FROM aropen AS target, aropen AS source
            WHERE ( (source.aropen_cust_id=target.aropen_cust_id)
             AND (target.aropen_doctype IN ('D', 'I'))
             AND (target.aropen_open)
             AND (source.aropen_id=pSourceAropenid)
             AND ((pTargetAropenid IS NULL) OR (target.aropen_id=pTargetAropenid)) )
            ORDER BY target.aropen_duedate, target.aropen_docnumber LOOP

--  Determine the amount to apply
    IF (_r.balance > _amount) THEN
      _applyAmount := _amount;
    ELSE
      _applyAmount := _r.balance;
    END IF;
    _applycurrid := _amountcurrid;

--  Does an arcreditapply record already exist?
    SELECT arcreditapply_id,
           arcreditapply_amount,
           arcreditapply_amount * _curr_rate / 
                 currRate(arcreditapply_curr_id,_r.docdate) AS
                      arcreditapply_amount_applycurr INTO _p
    FROM arcreditapply
    WHERE ( (arcreditapply_target_aropen_id=_r.aropenid)
     AND (arcreditapply_source_aropen_id=pSourceAropenid) );

    IF (FOUND) THEN
--  Offset the amount to apply by the amount already applied
      _applyAmount := (_applyAmount - _p.arcreditapply_amount_applycurr);
      IF (_applyAmount < 0) THEN
        _applyAmount := 0;
      END IF;

--  Update the arcreditapply with the new amount to apply
      UPDATE arcreditapply
      SET arcreditapply_amount = (arcreditapply_amount + 
          _applyAmount *  currRate(arcreditapply_curr_id,_r.docdate) / _curr_rate)
      WHERE (arcreditapply_id=_p.arcreditapply_id);

    ELSE
--  Create a new arcreditapply record
      INSERT INTO arcreditapply
      ( arcreditapply_source_aropen_id, arcreditapply_target_aropen_id,
        arcreditapply_amount, arcreditapply_curr_id )
      VALUES
      ( pSourceAropenid, _r.aropenid, _applyAmount, _applycurrid );
    END IF;

    _amount := _amount - currToCurr(_applycurrid, _amountcurrid, _applyAmount, _r.docdate);
    IF (_amount = 0) THEN
      EXIT;
    END IF;

  END LOOP;

  RETURN 1;

END;

Function: public.applycashreceiptlinebalance(integer, integer, numeric, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptId ALIAS FOR $1;
  pAropenid ALIAS FOR $2;
  pAmount ALIAS FOR $3;
  pCurrId ALIAS FOR $4;
  _balance NUMERIC;
  _amount NUMERIC;
  _applyAmount NUMERIC := 0;
  _discount NUMERIC := 0;
  _discprct NUMERIC;
  _docDate DATE;
  _r RECORD;
  _doctype CHAR(1);

BEGIN

--  All calculations performed in currency of Cash Receipt

--  Clear previously applied
  DELETE FROM cashrcptitem WHERE ((cashrcptitem_cashrcpt_id=pCashrcptId) AND (cashrcptitem_aropen_id=pAropenId));

--  Find the balance to apply
  SELECT (pAmount - (COALESCE(SUM(cashrcptitem_amount), 0) ) ),
    COALESCE(cashrcpt_docdate, current_date)
    INTO _amount, _docDate
  FROM cashrcpt LEFT OUTER JOIN cashrcptitem ON (cashrcptitem_cashrcpt_id = cashrcpt_id)
  WHERE (cashrcpt_id=pCashrcptid)
  GROUP BY cashrcpt_curr_id, cashrcpt_distdate, cashrcpt_docdate;

  SELECT (_amount - COALESCE(SUM(cashrcptmisc_amount), 0)) INTO _amount
  FROM cashrcptmisc
  WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid);

  SELECT aropen_doctype INTO _doctype
  FROM aropen
  WHERE (aropen_id=pAropenId);
  
  RAISE DEBUG 'Amount (%) DocType (%)', _amount, _doctype;

  IF (_amount <= 0 AND _doctype IN ('I','D')) THEN
    RETURN 0;
  END IF;

--  Determine Line balance
  SELECT currToCurr(aropen_curr_id, cashrcpt_curr_id,
         aropen_amount - aropen_paid, cashrcpt_distdate) -
         COALESCE((SELECT (SUM(cashrcptitem_amount) + SUM(cashrcptitem_discount))
                   FROM cashrcptitem, cashrcpt
                   WHERE ((cashrcpt_id=cashrcptitem_cashrcpt_id)
                     AND  (NOT cashrcpt_void)
                     AND  (NOT cashrcpt_posted)
                     AND  (cashrcpt_id != pCashrcptId)
                     AND  (cashrcptitem_aropen_id=pAropenId))), 0)
         INTO _balance
         FROM aropen, cashrcpt
           WHERE ((aropen_id=pAropenId)
           AND (cashrcpt_id=pCashrcptId));

  RAISE DEBUG 'Balance (%)', _balance;
            
--  If Invoice or Debit Memo, determine Max Discount as per Terms
  IF (_doctype IN ('I','D')) THEN
    SELECT  round(noNeg(_balance * 
            CASE WHEN (_docDate <= determineDiscountDate(terms_id, aropen_docdate)) THEN COALESCE(terms_discprcnt, 0.0) 
            ELSE 0.00 END - applied),2),
            CASE WHEN (_docDate <= determineDiscountDate(terms_id, aropen_docdate)) THEN COALESCE(terms_discprcnt, 0.0) 
            ELSE 0.00 END INTO _discount, _discprct
    FROM aropen LEFT OUTER JOIN terms ON (terms_id=aropen_terms_id), 
         (SELECT COALESCE(SUM(arapply_applied), 0.00) AS applied  
	  FROM arapply, aropen 
          WHERE ((arapply_target_aropen_id=pAropenId) 
           AND (arapply_source_aropen_id=pAropenId) 
           AND  (aropen_discount) )
             ) AS data 
    WHERE (aropen_id=pAropenId);

--  Determine the amount to apply
    IF (_balance <= _amount + _discount) THEN
      _applyAmount := _balance - _discount;
    ELSE
      _discount := round((_amount / (1 - _discprct)) - _amount, 2);
      _applyAmount := _amount;
    END IF;
  ELSIF (_doctype IN ('C', 'R')) THEN
  -- Handle Credits, discounts don't apply here
    _applyAmount := _balance * -1;
  ELSE
    _applyAmount := _amount;
  END IF;

  IF (_applyAmount != 0) THEN
--  Create a new cashrcptitem
      INSERT INTO cashrcptitem
      ( cashrcptitem_aropen_id, cashrcptitem_cashrcpt_id,
        cashrcptitem_amount,cashrcptitem_discount )
      VALUES
      ( pAropenid, pCashrcptid, round(_applyAmount, 2), round(_discount, 2) );
  END IF;

  RETURN abs(_applyAmount);

END;

Function: public.applycashreceipttobalance(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptid ALIAS FOR $1;
  pAmount ALIAS FOR $2;

BEGIN
  RETURN applyCashReceiptToBalance(pCashrcptid, pAmount, baseCurrId() );
END;

Function: public.applycashreceipttobalance(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptid ALIAS FOR $1;
  pAmount ALIAS FOR $2;
  pCurrId ALIAS FOR $3;

BEGIN

  RETURN applyCashReceiptToBalance(pCashrcptid, pAmount, pCurrId, false);

END;

Function: public.applycashreceipttobalance(integer, numeric, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptid ALIAS FOR $1;
  pAmount ALIAS FOR $2;
  pCurrId ALIAS FOR $3;
  pInclCredits ALIAS FOR $4;
  _amount NUMERIC;
  _applied NUMERIC := 0;
  _applyAmount NUMERIC;
  _discount NUMERIC;
  _discprct NUMERIC;
  _docDate DATE;
  _r RECORD;
  _toApply NUMERIC;

BEGIN

--  Apply open credits first if applicable
  IF (pInclCredits) THEN
    -- First find total debits unaccounted for by this receipt so we can apply as much credit 
    -- as possible to clear, but no more
    SELECT coalesce(noNeg(sum(currToCurr(aropen_curr_id, cashrcpt_curr_id,
         aropen_amount - aropen_paid, cashrcpt_distdate) -
         COALESCE((SELECT (SUM(cashrcptitem_amount) + SUM(cashrcptitem_discount))
                   FROM cashrcptitem, cashrcpt
                   WHERE ((cashrcpt_id=cashrcptitem_cashrcpt_id)
                     AND  (NOT cashrcpt_void)
                     AND  (NOT cashrcpt_posted)
                     AND  (cashrcpt_id != pCashrcptid)
                     AND  (cashrcptitem_aropen_id=aropen_id))), 0)) - pAmount),0)
    INTO _toApply
    FROM cashrcpt
      JOIN custinfo ON (cashrcpt_cust_id=cust_id)
      JOIN aropen ON (cust_id=aropen_cust_id)
    WHERE ((cashrcpt_id=pCashrcptid)
      AND (aropen_open)
      AND (aropen_doctype IN ('I','D')));
           
    -- Loop through and apply credits until we account for all remaining debits we can
    FOR _r IN 
      SELECT aropen_id
      FROM cashrcpt
        JOIN custinfo ON (cashrcpt_cust_id=cust_id)
        JOIN aropen ON (cust_id=aropen_cust_id)
      WHERE ((cashrcpt_id=pCashrcptid)
        AND (aropen_open)
        AND (aropen_doctype IN ('C','R')))
      ORDER BY aropen_duedate, aropen_docnumber
    LOOP
     EXIT WHEN _toApply <= 0;
      _toApply := _toApply - applyCashReceiptLineBalance(pCashrcptid, _r.aropen_id, _toApply, pCurrId);
    END LOOP;
  END IF;

--  Find the balance to apply
  SELECT (currToCurr(pCurrId, cashrcpt_curr_id, pAmount, cashrcpt_distdate) -
              (COALESCE(SUM(cashrcptitem_amount), 0) ) ),
              COALESCE(cashrcpt_docdate, current_date) 
              INTO _amount, _docDate
  FROM cashrcpt LEFT OUTER JOIN cashrcptitem ON (cashrcptitem_cashrcpt_id = cashrcpt_id)
  WHERE (cashrcpt_id=pCashrcptid)
  GROUP BY cashrcpt_curr_id, cashrcpt_distdate, cashrcpt_docdate;

  SELECT (_amount - COALESCE(SUM(cashrcptmisc_amount), 0)) INTO _amount
  FROM cashrcptmisc
  WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid);

  IF (_amount = 0) THEN
    RETURN 1;
  END IF;

--  Loop through the aropen item in order of due date, searching only for
--  aropen items that are open, for the current customer and have an outstanding balance
  FOR _r IN SELECT aropen_id,
               currToCurr(aropen_curr_id, cashrcpt_curr_id,
               aropen_amount - aropen_paid, cashrcpt_distdate) -
               COALESCE((SELECT SUM(cashrcptitem_amount) + SUM(cashrcptitem_discount)
                           FROM cashrcptitem, cashrcpt
                           WHERE ((cashrcpt_id=cashrcptitem_cashrcpt_id)
                             AND  (NOT cashrcpt_void)
                             AND  (NOT cashrcpt_posted)
                             AND  (cashrcpt_id != pCashrcptId)
                             AND  (cashrcptitem_aropen_id=aropen_id))), 0) AS balance,
                   s.cashrcptitem_id AS cashrcptitem_id
            FROM cashrcpt, aropen LEFT OUTER JOIN
                 cashrcptitem s ON (s.cashrcptitem_aropen_id=aropen_id AND s.cashrcptitem_cashrcpt_id=pCashrcptId)
                 LEFT OUTER JOIN terms ON (aropen_terms_id=terms_id),
                 (SELECT COALESCE(SUM(arapply_applied), 0.00) AS applied  
                  FROM arapply, aropen 
                  WHERE ((arapply_target_aropen_id=aropen_id) 
                    AND (arapply_source_aropen_id=aropen_id) 
                    AND  (aropen_discount) )
                 ) AS data

            WHERE ( (aropen_cust_id=cashrcpt_cust_id)
             AND (aropen_doctype IN ('I', 'D'))
             AND (aropen_open)
             AND (cashrcpt_id=pCashrcptid) )
            ORDER BY aropen_duedate, aropen_amount, balance LOOP

--  Determine Max Discount as per Terms
    SELECT  round(noNeg(_r.balance * 
            CASE WHEN (_docDate <= determineDiscountDate(terms_id, aropen_docdate)) THEN terms_discprcnt 
            ELSE 0.00 END - applied),2),
            CASE WHEN (_docDate <= determineDiscountDate(terms_id, aropen_docdate)) THEN terms_discprcnt 
            ELSE 0.00 END INTO _discount, _discprct
            FROM aropen LEFT OUTER JOIN terms ON (terms_id=aropen_terms_id), 
                 (SELECT COALESCE(SUM(arapply_applied), 0.00) AS applied  
		          FROM arapply, aropen 
                  WHERE ((arapply_target_aropen_id=_r.aropen_id) 
                  AND (arapply_source_aropen_id=_r.aropen_id) 
                  AND  (aropen_discount) )
                 ) AS data 
            WHERE (aropen_id=_r.aropen_id);

--  Determine the amount to apply
    IF (_r.balance <= _amount + _discount) THEN
      _applyAmount := _r.balance - _discount;
    ELSE
      _discount := round((_amount / (1 - _discprct)) - _amount, 2);
      _applyAmount := _amount;
    END IF;

    IF (_applyAmount > 0) THEN
--  Does an cashrcptitem already exist?
      IF (_r.cashrcptitem_id IS NOT NULL) THEN
--  Update the cashrcptitem with the new amount to apply
        UPDATE cashrcptitem
        SET cashrcptitem_amount = round(cashrcptitem_amount + _applyAmount, 2),
            cashrcptitem_discount = round(_discount, 2)
        WHERE (cashrcptitem_id=_r.cashrcptitem_id);
      ELSE
--  Create a new cashrcptitem
        INSERT INTO cashrcptitem
        ( cashrcptitem_aropen_id, cashrcptitem_cashrcpt_id,
          cashrcptitem_amount, cashrcptitem_discount )
        VALUES
        ( _r.aropen_id, pCashrcptid, round(_applyAmount, 2), round(_discount, 2) );
      END IF;

      _amount := (_amount - _applyAmount);
      IF (round(_amount, 2) = 0) THEN
        EXIT;
      END IF;

    END IF;
  END LOOP;

  RETURN 1;

END;

Function: public.araging(date, boolean)

Returns: SET OF araging

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAsOfDate ALIAS FOR $1;
  pUseDocDate ALIAS FOR $2;
  _row araging%ROWTYPE;

BEGIN

  FOR _row IN SELECT *
            FROM araging(pAsOfDate, pUseDocDate, true)
  LOOP
    RETURN NEXT _row;
  END LOOP;

  RETURN;
END;

Function: public.araging(date, boolean, boolean)

Returns: SET OF araging

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAsOfDate ALIAS FOR $1;
  pUseDocDate ALIAS FOR $2;
  pConvBaseCurr ALIAS FOR $3;
  _row araging%ROWTYPE;
  _x RECORD;
  _returnVal INTEGER;
  _asOfDate DATE;
BEGIN

  _asOfDate := COALESCE(pAsOfDate,current_date);

  FOR _x IN
        SELECT
        --report uses currtobase to convert all amounts to base based on aropen_docdate to ensure the same exchange rate

        --today and greater base:
        CASE WHEN((aropen_duedate >= DATE(_asOfDate))) 
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS cur_val,

        --0 to 30 base
        CASE WHEN((aropen_duedate >= DATE(_asOfDate)-30) AND (aropen_duedate < DATE(_asOfDate)))
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS thirty_val,

        --30-60 base
        CASE WHEN((aropen_duedate >= DATE(_asOfDate)-60) AND (aropen_duedate < DATE(_asOfDate) - 30 ))
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS sixty_val,

        --60-90 base
        CASE WHEN((aropen_duedate >= DATE(_asOfDate)-90) AND (aropen_duedate < DATE(_asOfDate) - 60))
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS ninety_val,

        --greater than 90 base:
        CASE WHEN((aropen_duedate > DATE(_asOfDate)-10000) AND (aropen_duedate < DATE(_asOfDate) - 90))
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS plus_val,

        --total amount base:
        CASE WHEN((aropen_duedate > DATE(_asOfDate)-10000)) 
        THEN (((aropen_amount-aropen_paid+COALESCE(SUM(arapply_target_paid),0)))/
        CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END *
        CASE WHEN (aropen_doctype IN ('C', 'R')) THEN -1 ELSE 1 END) ELSE 0 END AS total_val,

        --AR Open Amount base
        CASE WHEN aropen_doctype IN ('C', 'R') 
        THEN (aropen_amount * -1) / CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END
        ELSE aropen_amount / CASE WHEN (pConvBaseCurr) THEN aropen_curr_rate ELSE 1.0 END END AS aropen_amount,

        aropen_docdate,
        aropen_duedate,
        aropen_ponumber,
        aropen_docnumber,
        aropen_doctype,
        cust_id,
        cust_name,
        cust_number,
        cust_custtype_id,
        custtype_code,
        COALESCE(arterms.terms_descrip, custterms.terms_descrip, '') AS terms_descrip

        FROM aropen
          JOIN custinfo ON (cust_id=aropen_cust_id)
          JOIN custtype ON (custtype_id=cust_custtype_id)
          LEFT OUTER JOIN terms arterms ON (arterms.terms_id=aropen_terms_id)
          LEFT OUTER JOIN terms custterms ON (custterms.terms_id=cust_terms_id)
          LEFT OUTER JOIN arapply ON (((aropen_id=arapply_target_aropen_id)
                                    OR (aropen_id=arapply_source_aropen_id))
                                   AND (arapply_distdate>_asOfDate))
        WHERE ( (CASE WHEN (pUseDocDate) THEN aropen_docdate ELSE aropen_distdate END <= _asOfDate)
        AND (COALESCE(aropen_closedate,_asOfDate+1)>_asOfDate) )
        GROUP BY aropen_id,aropen_docdate,aropen_duedate,aropen_ponumber,aropen_docnumber,aropen_doctype,aropen_paid,
                 aropen_curr_id,aropen_amount,cust_id,cust_name,cust_number,cust_custtype_id,custtype_code,
                 arterms.terms_descrip,custterms.terms_descrip, aropen_curr_rate
        ORDER BY cust_number, aropen_duedate
  LOOP
        _row.araging_docdate := _x.aropen_docdate;
        _row.araging_duedate := _x.aropen_duedate;
        _row.araging_ponumber := _x.aropen_ponumber;
        _row.araging_docnumber := _x.aropen_docnumber;
        _row.araging_doctype := _x.aropen_doctype;
        _row.araging_cust_id := _x.cust_id;
        _row.araging_cust_number := _x.cust_number;
        _row.araging_cust_name := _x.cust_name;
        _row.araging_cust_custtype_id := _x.cust_custtype_id;
        _row.araging_custtype_code := _x.custtype_code;
        _row.araging_terms_descrip := _x.terms_descrip;
        _row.araging_aropen_amount := _x.aropen_amount;
        _row.araging_cur_val := _x.cur_val;
        _row.araging_thirty_val := _x.thirty_val;
        _row.araging_sixty_val := _x.sixty_val;
        _row.araging_ninety_val := _x.ninety_val;
        _row.araging_plus_val := _x.plus_val;
        _row.araging_total_val := _x.total_val;
        RETURN NEXT _row;
  END LOOP;
  RETURN;
END;

Function: public.arapplied(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAropenid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  _amount NUMERIC;

BEGIN

  -- Return amount applied to an aropen in base currency item as of the parameter date
  SELECT SUM(currtobase(arapply_curr_id,arapply_applied,pDate)) INTO _amount
  FROM arapply
  WHERE (((arapply_target_aropen_id = pAropenid) OR (arapply_source_aropen_id = pAropenid))
  AND (((arapply_journalnumber=0) AND (arapply_postdate <= pDate))
  OR EXISTS(SELECT * 
             FROM gltrans 
             WHERE ((gltrans_journalnumber=arapply_journalnumber)
             AND (gltrans_date <= pDate)))));

  IF (_amount IS NULL) THEN
    RETURN 0;
  ELSE
    RETURN _amount;
  END IF;

END;

Function: public.archivesaleshistory(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSohistid ALIAS FOR $1;

BEGIN

  INSERT INTO asohist ( asohist_id,
                        asohist_cust_id,
                        asohist_itemsite_id,
                        asohist_shipdate,
                        asohist_invcdate,
                        asohist_duedate,
                        asohist_promisedate,
                        asohist_ordernumber,
                        asohist_invcnumber,
                        asohist_qtyshipped,
                        asohist_unitprice,
                        asohist_unitcost,
                        asohist_billtoname,
                        asohist_billtoaddress1,
                        asohist_billtoaddress2,
                        asohist_billtoaddress3,
                        asohist_billtocity,
                        asohist_billtostate,
                        asohist_billtozip,
                        asohist_shiptoname,
                        asohist_shiptoaddress1,
                        asohist_shiptoaddress2,
                        asohist_shiptoaddress3,
                        asohist_shiptocity,
                        asohist_shiptostate,
                        asohist_shiptozip,
                        asohist_shipto_id,
                        asohist_shipvia,
                        asohist_salesrep_id,
                        asohist_misc_type,
                        asohist_misc_descrip,
                        asohist_misc_id,
                        asohist_commission,
                        asohist_commissionpaid,
                        asohist_doctype,
                        asohist_orderdate,
                        asohist_imported,
			asohist_ponumber,
                        asohist_curr_id,
                        asohist_taxtype_id,
                        asohist_taxzone_id )
  SELECT cohist_id,
         cohist_cust_id,
         cohist_itemsite_id,
         cohist_shipdate,
         cohist_invcdate,
         cohist_duedate,
         cohist_promisedate,
         cohist_ordernumber,
         cohist_invcnumber,
         cohist_qtyshipped,
         cohist_unitprice,
         cohist_unitcost,
         cohist_billtoname,
         cohist_billtoaddress1,
         cohist_billtoaddress2,
         cohist_billtoaddress3,
         cohist_billtocity,
         cohist_billtostate,
         cohist_billtozip,
         cohist_shiptoname,
         cohist_shiptoaddress1,
         cohist_shiptoaddress2,
         cohist_shiptoaddress3,
         cohist_shiptocity,
         cohist_shiptostate,
         cohist_shiptozip,
         cohist_shipto_id,
         cohist_shipvia,
         cohist_salesrep_id,
         cohist_misc_type,
         cohist_misc_descrip,
         cohist_misc_id,
         cohist_commission,
         cohist_commissionpaid,
         cohist_doctype,
         cohist_orderdate,
         cohist_imported,
         cohist_ponumber,
	 cohist_curr_id,
         cohist_taxtype_id,
         cohist_taxzone_id
  FROM cohist
  WHERE (cohist_id=pSohistid);

  INSERT INTO asohisttax ( taxhist_id,
                           taxhist_parent_id,
                           taxhist_taxtype_id,
                           taxhist_tax_id,
                           taxhist_basis,
                           taxhist_basis_tax_id,
                           taxhist_sequence,
                           taxhist_percent,
                           taxhist_amount,
                           taxhist_tax,
                           taxhist_docdate,
                           taxhist_distdate,
                           taxhist_curr_id,
                           taxhist_curr_rate,
                           taxhist_journalnumber )
  SELECT taxhist_id,
         taxhist_parent_id,
         taxhist_taxtype_id,
         taxhist_tax_id,
         taxhist_basis,
         taxhist_basis_tax_id,
         taxhist_sequence,
         taxhist_percent,
         taxhist_amount,
         taxhist_tax,
         taxhist_docdate,
         taxhist_distdate,
         taxhist_curr_id,
         taxhist_curr_rate,
         taxhist_journalnumber
  FROM cohisttax
  WHERE (taxhist_parent_id=pSohistid);

  DELETE FROM cohisttax
  WHERE (taxhist_parent_id=pSohistid);

  DELETE FROM cohist
  WHERE (cohist_id=pSohistid);

  RETURN pSohistid;

END;

Function: public.arcurrgain(integer, integer, numeric, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAropenId ALIAS FOR $1;
  pCurrId ALIAS FOR $2;
  pValue ALIAS FOR $3;
  pDate ALIAS FOR $4;
  _start DATE;
  _end DATE;
  _gain NUMERIC;
  _r RECORD;

BEGIN
  IF (pAropenId IS NULL OR pValue = 0) THEN
    RETURN 0;
  END IF;

  SELECT aropen_docdate, aropen_curr_id, aropen_curr_rate
    INTO _r
  FROM aropen
  WHERE (aropen_id=pAropenId);

  IF (_r.aropen_docdate > pDate) THEN
    _gain := (currToBase(pCurrId, pValue, pDate) - currToCurr(pCurrId,_r.aropen_curr_id, pValue, pDate) / _r.aropen_curr_rate) * -1;
  ELSE
    _gain := currToCurr(pCurrId,_r.aropen_curr_id, pValue, pDate) / _r.aropen_curr_rate - currToBase(pCurrId, pValue, pDate);
  END IF;

  IF (_gain IS NULL) THEN
    RAISE EXCEPTION 'Error processing currency gain/loss.';
  END IF;

  RETURN _gain;
END;

Function: public.armor(bytea)

Returns: text

Language: C

pg_armor

Function: public.asofinvbal(integer, date)

Returns: SET OF invbal

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  pAsofDate ALIAS FOR $2;
  _result invbal%ROWTYPE;
  _i RECORD;
  _h RECORD;
  _r RECORD;
  _prevCostmethod TEXT := 'A';
  _prevDate TIMESTAMP WITH TIME ZONE;
  _runningQty NUMERIC := 0;
  _runningNn NUMERIC := 0;
  _runningValue NUMERIC := 0;
  _runningNnval NUMERIC := 0;

BEGIN
  /* This is a base function to gather data.  Because it is STABLE it should only need
  to be calculated once, even though it is likely to be called several times by other
  functions in parent query to present the various data.
  */
  
  -- First make sure inventory balance is forward updated
  PERFORM forwardUpdateItemsite(pItemsiteId);

  -- Next find the previous period balace to use as a starting point
  SELECT invbal.*, period_start, itemsite_costmethod INTO _i
  FROM invbal 
    JOIN itemsite ON (invbal_itemsite_id=itemsite_id) 
    JOIN period ON (invbal_period_id=period_id)
  WHERE ((invbal_itemsite_id=pItemsiteId)
    AND  (pAsofDate >= period_start))
  ORDER BY period_start DESC
  LIMIT 1;

  _runningQty := _i.invbal_qoh_beginning;
  _runningNn := _i.invbal_nn_beginning;
  _runningValue := _i.invbal_value_beginning;
  _runningNnval := _i.invbal_nnval_beginning;
  _prevDate := _i.period_start;
  _prevCostmethod := _i.itemsite_costmethod;

  FOR _r IN 
    SELECT invhist_id, invhist_created, invhist_invqty, invhist_transtype, invhist_unitcost,
      invhist_costmethod, itemsite_item_id, invhistSense(invhist_id) AS sense
    FROM invhist
      JOIN itemsite ON (itemsite_id=invhist_itemsite_id)
    WHERE ((invhist_itemsite_id=pItemsiteId)
    AND (invhist_transdate::date BETWEEN _i.period_start AND pAsofdate))
    ORDER BY invhist_created, invhist_id
  LOOP
    -- Update balances changed by any standard cost update between transactions
    IF (_prevCostmethod = 'S' AND _runningQty != 0) THEN
      FOR _h IN
        SELECT costhist_oldcost, costhist_newcost
        FROM costhist
          JOIN item ON (costhist_item_id=item_id)
          JOIN itemsite ON (itemsite_item_id=item_id)
        WHERE ((itemsite_id=pItemsiteId)
          AND (costhist_date BETWEEN _prevDate AND _r.invhist_created)
          AND (costhist_type IN ('S','D')))
      LOOP
        _runningValue := _runningValue + round((_h.costhist_newcost-_h.costhist_oldcost) * _runningQty,2);
        _runningNnval := _runningNnval + round((_h.costhist_newcost-_h.costhist_oldcost) * _runningNn,2);
      END LOOP;
    END IF;

    _prevDate := _r.invhist_created;
    _prevCostmethod := _r.invhist_costmethod;
    _runningQty := _runningQty + _r.invhist_invqty * _r.sense;
    _runningValue := _runningValue + round( _r.invhist_invqty * _r.sense * _r.invhist_unitcost,2);
    IF (_r.invhist_transtype = 'NN') THEN
      _runningNn := _runningNn + _r.invhist_invqty * -1;
      _runningNnval := _runningNnval + round( _r.invhist_invqty * -1 * _r.invhist_unitcost,2);
    END IF;
    
  END LOOP;

  _prevDate := COALESCE(_prevDate, _i.period_start);
  _prevCostmethod := COALESCE(_r.invhist_costmethod, _i.itemsite_costmethod);
  
  IF (_prevCostmethod = 'S' AND _runningQty != 0) THEN
    FOR _h IN
      SELECT costhist_oldcost, costhist_newcost
      FROM costhist
        JOIN item ON (costhist_item_id=item_id)
        JOIN itemsite ON (itemsite_item_id=item_id)
      WHERE ((itemsite_id=pItemsiteId)
        AND (costhist_date BETWEEN _prevDate AND CAST(pAsofDate + 1 AS TIMESTAMP WITH TIME ZONE))
        AND (costhist_type IN ('S','D')))
    LOOP
      _runningValue := _runningValue + round((_h.costhist_newcost-_h.costhist_oldcost) * _runningQty,2);
      _runningNnval := _runningNnval + round((_h.costhist_newcost-_h.costhist_oldcost) * _runningNn,2);
    END LOOP;
  END IF;

  _result := _i;
  _result.invbal_qoh_ending := _runningQty;
  _result.invbal_value_ending := _runningValue;
  _result.invbal_nn_ending := _runningNn;
  _result.invbal_nnval_ending := _runningNnval;

  RETURN NEXT _result;

  RETURN;
  
END;

Function: public.asofinvnn(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  pAsofDate ALIAS FOR $2;
  _result NUMERIC;

BEGIN

  SELECT invbal_nn_ending INTO _result
  FROM asofinvbal(pItemsiteId, pAsofDate);

  RETURN COALESCE(_result, 0);
  
END;

Function: public.asofinvqty(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  pAsofDate ALIAS FOR $2;
  _result NUMERIC;

BEGIN

  SELECT invbal_qoh_ending INTO _result
  FROM asofinvbal(pItemsiteId, pAsofDate);

  RETURN COALESCE(_result, 0);
  
END;

Function: public.attachcontact(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcntctId    ALIAS FOR $1;
  pcrmacctId  ALIAS FOR $2;
BEGIN
  UPDATE cntct SET cntct_crmacct_id = pcrmacctId
  WHERE cntct_id = pcntctId;

  RETURN 0;
END;

Function: public.attachquotetoopportunity(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid	ALIAS FOR $1;
  pOpheadid	ALIAS FOR $2;
BEGIN

-- Check Quote
  IF (NOT EXISTS(SELECT quhead_id
                 FROM quhead
                 WHERE (quhead_id=pQuheadid))) THEN
    RETURN -1;
  END IF;

-- Check Opportunity
  IF (NOT EXISTS(SELECT ophead_id
                 FROM ophead
                 WHERE (ophead_id=pOpheadid))) THEN
    RETURN -2;
  END IF;

-- Cannot attach if already attached
  IF (EXISTS(SELECT quhead_id
	     FROM quhead
	     WHERE ((quhead_id=pQuheadid)
	       AND  (quhead_ophead_id IS NOT NULL)))) THEN
    RETURN -3;
  END IF;

  UPDATE quhead SET quhead_ophead_id=pOpheadid
  WHERE (quhead_id=pQuheadid);

  RETURN 0;

END;

Function: public.attachsalesordertoopportunity(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid	ALIAS FOR $1;
  pOpheadid	ALIAS FOR $2;
BEGIN

-- Check Sales Order
  IF (NOT EXISTS(SELECT cohead_id
                 FROM cohead
                 WHERE (cohead_id=pSoheadid))) THEN
    RETURN -1;
  END IF;

-- Check Opportunity
  IF (NOT EXISTS(SELECT ophead_id
                 FROM ophead
                 WHERE (ophead_id=pOpheadid))) THEN
    RETURN -2;
  END IF;

-- Cannot attach if already attached
  IF (EXISTS(SELECT cohead_id
	     FROM cohead
	     WHERE ((cohead_id=pSoheadid)
	       AND  (cohead_ophead_id IS NOT NULL)))) THEN
    RETURN -3;
  END IF;

  UPDATE cohead SET cohead_ophead_id=pOpheadid
  WHERE (cohead_id=pSoheadid);

  RETURN 0;

END;

Function: public.averagesalesprice(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _p RECORD;

BEGIN
-- Returns value in base currency
-- ToDo: is cohist_shipdate the right DATE to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitprice,
                                            cohist_shipdate)) AS totalsales,
         SUM(cohist_qtyshipped) AS totalship INTO _p
  FROM cohist
  WHERE ( (cohist_itemsite_id=pItemsiteid)
   AND (cohist_invcdate BETWEEN pStartDate AND pEndDate) );

  IF ( (_p.totalship IS NULL) OR
       (_p.totalship = 0) ) THEN
    RETURN 0;
  ELSE
    RETURN (_p.totalsales / _p.totalship);
  END IF;

END;

Function: public.avgcost(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _value NUMERIC;
  _qoh NUMERIC;
BEGIN
  SELECT itemsite_value, itemsite_qtyonhand
    INTO _value, _qoh
    FROM itemsite
   WHERE(itemsite_id=pItemsiteid);
  IF (_qoh = 0) THEN
    RETURN 0;
  END IF;
  RETURN _value / _qoh;
END;

Function: public.balanceitemsite(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _itemlocseries INTEGER;
  _balanced NUMERIC;
  _qoh NUMERIC;
  _nnQoh NUMERIC;

BEGIN

--  Make sure that that passed Itemsite is MLC or Lot/Serial controlled
  IF ( ( SELECT (NOT ( (itemsite_loccntrl) OR (itemsite_controlmethod IN ('L', 'S')) ))
         FROM itemsite
         WHERE (itemsite_id=pItemsiteid) ) ) THEN
    RETURN 0;
  END IF;

  IF ( ( SELECT itemsite_freeze
           FROM itemsite
          WHERE(itemsite_id=pItemsiteid) ) ) THEN
    RETURN -1;
  END IF;

--  Calculate the Netable portion
  SELECT COALESCE(SUM(itemloc_qty), 0) INTO _balanced
  FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
  WHERE ( ( (location_id IS NULL) OR (location_netable) )
   AND (itemloc_itemsite_id=pItemsiteid) );

--  Post an AD Transaction for the Netable portion
  SELECT invAdjustment( itemsite_id, (_balanced - itemsite_qtyonhand),
                        'Balance', 'Inventory Balance' ) INTO _itemlocseries
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

--  Post the invtrans records associated with the itemlocdist records
  PERFORM postInvhist(itemlocdist_invhist_id)
     FROM itemlocdist
    WHERE(itemlocdist_series=_itemlocseries);

--  Kill the resultant distribution records
  DELETE FROM itemlocdist
  WHERE (itemlocdist_series=_itemlocseries);

--  Calculate and write the Non-Netable portion directly
  SELECT COALESCE(SUM(itemloc_qty), 0) INTO _nnQoh
  FROM itemloc, location
  WHERE ( (itemloc_location_id=location_id)
   AND (NOT location_netable)
   AND (itemloc_itemsite_id=pItemsiteid) );

  UPDATE itemsite
  SET itemsite_nnqoh = _nnQoh
  WHERE (itemsite_id=pItemsiteid);

  RETURN 1;

END;

Function: public.basecurrid()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  returnVal INTEGER;
BEGIN
  SELECT curr_id INTO returnVal
    FROM curr_symbol
   WHERE curr_base = TRUE;
  IF NOT FOUND THEN
    RAISE EXCEPTION 'No base currency found';
  END IF;
  RETURN returnVal;
END;

Function: public.bomcontains(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pparentitemid	ALIAS FOR $1;
  pchilditemid	ALIAS FOR $2;
  _bomworksetid	INTEGER;
  _result	BOOLEAN;

BEGIN
  _bomworksetid := indentedWhereUsed(pchilditemid);
  _result := EXISTS(SELECT bomwork_id
		    FROM bomwork
		    WHERE ((bomwork_set_id=_bomworksetid)
		      AND  (bomwork_item_id=pparentitemid) ));

  PERFORM deleteBOMWorkset(_bomworksetid);

  RETURN _result;
END;

Function: public.bomhistsequence(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pHistid ALIAS FOR $1;
  _wid INTEGER;
  _seqnum TEXT;
  _bomhist RECORD;

BEGIN
  _wid := pHistid;

  SELECT bomhist_parent_id AS parent,
         to_char(bomhist_seqnumber, '00009') AS seq INTO _bomhist
    FROM bomhist
   WHERE bomhist_seq_id=_wid;

  IF (FOUND) THEN
    _seqnum := _bomhist.seq;
    _wid := _bomhist.parent;

    WHILE (_wid != -1) LOOP
      SELECT bomhist_parent_id AS parent,
             to_char(bomhist_seqnumber, '00009') AS seq INTO _bomhist
      FROM bomhist
      WHERE bomhist_seq_id=_wid;

      IF (FOUND) THEN
        _seqnum := _bomhist.seq || '-' || _seqnum;
        _wid    := _bomhist.parent;
      ELSE
        _wid := -1;
      END IF;
    END LOOP;
  ELSE
    _seqnum := ''::TEXT;
  END IF;

  RETURN _seqnum;
END;

Function: public.bomitem(integer)

Returns: SET OF bomitem

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT * FROM bomitem WHERE ((bomitem_parent_item_id=$1) AND (bomitem_rev_id=getActiveRevId('BOM',$1)));

Function: public.bomitem(integer, integer)

Returns: SET OF bomitem

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT * FROM bomitem WHERE ((bomitem_parent_item_id=$1) AND (bomitem_rev_id=$2));

Function: public.bomlevelbyitem(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _cnt INTEGER;
  _result INTEGER;
  _bomitem RECORD;

BEGIN
  _cnt := 0;

  BEGIN
  FOR _bomitem IN SELECT bomitem_parent_item_id
                    FROM bomitem
                   WHERE (bomitem_item_id=pItemid) LOOP
    SELECT bomLevelByItem(_bomitem.bomitem_parent_item_id) + 1 INTO _result;
    IF (_result > _cnt) THEN
      _cnt := _result;
    END IF;
  END LOOP;
  EXCEPTION WHEN statement_too_complex THEN
      RAISE EXCEPTION 'potential recursive BOM found for item_id %', pItemid;
  END;

  return _cnt;
END;

Function: public.bomlevelbyitem(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pBomrevid ALIAS FOR $2;
  _cnt INTEGER;
  _result INTEGER;
  _bomitem RECORD;

BEGIN
  _cnt := 0;

  BEGIN
  FOR _bomitem IN SELECT bomitem_parent_item_id
                    FROM bomitem
                   WHERE ((bomitem_item_id=pItemid)
                     AND  (bomitem_rev_id=pBomrevid)) LOOP
    SELECT bomLevelByItem(_bomitem.bomitem_parent_item_id, pBomrevid) + 1 INTO _result;
    IF (_result > _cnt) THEN
      _cnt := _result;
    END IF;
  END LOOP;
  EXCEPTION WHEN statement_too_complex THEN
      RAISE EXCEPTION 'potential recursive BOM found for item_id %', pItemid;
  END;

  return _cnt;
END;

Function: public.bomworkeffective(integer, date)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    workid ALIAS FOR $1;
    effdate ALIAS FOR $2;
    _wid INTEGER;
    _bomwork RECORD;
BEGIN
    _wid := workid;
    WHILE (_wid != -1) LOOP
        SELECT bomwork_parent_id AS parent,
               bomwork_effective AS effective
          INTO _bomwork
          FROM bomwork
         WHERE bomwork_id=_wid;

         IF (FOUND) THEN
             _wid := _bomwork.parent;
             IF (_bomwork.effective > effdate) THEN
                 RETURN FALSE;
             END IF;
         ELSE
             _wid := -1;
         END IF;
    END LOOP;
    RETURN TRUE;
END;

Function: public.bomworkexpired(integer, date)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    workid ALIAS FOR $1;
    expdate ALIAS FOR $2;
    _wid INTEGER;
    _bomwork RECORD;
BEGIN
    _wid := workid;
    WHILE (_wid != -1) LOOP
        SELECT bomwork_parent_id AS parent,
               bomwork_expires AS expires
          INTO _bomwork
          FROM bomwork
         WHERE bomwork_id=_wid;

         IF (FOUND) THEN
             _wid := _bomwork.parent;
             IF (_bomwork.expires <= expdate) THEN
                 RETURN TRUE;
             END IF;
         ELSE
             _wid := -1;
         END IF;
    END LOOP;
    RETURN FALSE;
END;

Function: public.bomworkitemsequence(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWorkid ALIAS FOR $1;
  _wid INTEGER;
  _seqnum TEXT;
  _bomwork RECORD;

BEGIN
  _wid := pWorkid;

  SELECT bomwork_parent_id AS parent,
         item_number AS seq INTO _bomwork
    FROM bomwork, item
   WHERE ((bomwork_id=_wid)
   AND (bomwork_item_id=item_id));

  IF (FOUND) THEN
    _seqnum := _bomwork.seq;
    _wid := _bomwork.parent;

    WHILE (_wid != -1) LOOP
      SELECT bomwork_parent_id AS parent,
             item_number AS seq INTO _bomwork
      FROM bomwork, item
      WHERE ((bomwork_id=_wid)
      AND (bomwork_item_id=item_id));

      IF (FOUND) THEN
        _seqnum := _bomwork.seq || '-' || _seqnum;
        _wid    := _bomwork.parent;
      ELSE
        _wid := -1;
      END IF;
    END LOOP;
  ELSE
    _seqnum := ''::TEXT;
  END IF;

  RETURN _seqnum;
END;

Function: public.bomworksequence(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWorkid ALIAS FOR $1;
  _wid INTEGER;
  _seqnum TEXT;
  _bomwork RECORD;

BEGIN
  _wid := pWorkid;

  SELECT bomwork_parent_id AS parent,
         to_char(bomwork_seqnumber, '00009') AS seq INTO _bomwork
    FROM bomwork
   WHERE bomwork_id=_wid;

  IF (FOUND) THEN
    _seqnum := _bomwork.seq;
    _wid := _bomwork.parent;

    WHILE (_wid != -1) LOOP
      SELECT bomwork_parent_id AS parent,
             to_char(bomwork_seqnumber, '00009') AS seq INTO _bomwork
      FROM bomwork
      WHERE bomwork_id=_wid;

      IF (FOUND) THEN
        _seqnum := _bomwork.seq || '-' || _seqnum;
        _wid    := _bomwork.parent;
      ELSE
        _wid := -1;
      END IF;
    END LOOP;
  ELSE
    _seqnum := ''::TEXT;
  END IF;

  RETURN _seqnum;
END;

Function: public.buildinvbal(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  _r RECORD;
  _prevCostmethod TEXT := 'A';
  _prevDate TIMESTAMP WITH TIME ZONE;
  _runningQty NUMERIC := 0;
  _runningNn NUMERIC := 0;

BEGIN
  -- Validate
  IF (SELECT (count(invhist_id) > 0)
      FROM invhist
      WHERE ((invhist_itemsite_id=pItemsiteId)
      AND (NOT invhist_posted))) THEN

    SELECT item_number, warehous_code INTO _r
    FROM itemsite
      JOIN item ON (item_id=itemsite_item_id)
      JOIN whsinfo ON (itemsite_warehous_id=warehous_id)
    WHERE (itemsite_id=pItemsiteId);
    
    RAISE EXCEPTION 'Unposted inventory transactions exist for % at % [xtuple: buildInvBal, -1, %, %]',
                    _r.item_number, _r.warehous_code,
                    _r.item_number, _r.warehous_code;
  END IF;

  -- Remove any old records
  DELETE FROM invbal WHERE invbal_itemsite_id=pItemsiteId;

  FOR _r IN 
    SELECT invhist_id, invhist_created, invhist_invqty, invhist_transtype,
      invhist_costmethod, itemsite_item_id, invhistSense(invhist_id) AS sense,
      item_number, warehous_code
    FROM invhist
      JOIN itemsite ON (itemsite_id=invhist_itemsite_id)
      JOIN item ON (itemsite_item_id=item_id)
      JOIN whsinfo ON (itemsite_warehous_id=warehous_id)
    WHERE (invhist_itemsite_id=pItemsiteId)
    ORDER BY invhist_created, invhist_id
  LOOP
    RAISE NOTICE 'Calculating balances for Item % at Site % against transaction %', _r.item_number, _r.warehous_code, _r.invhist_id;
    -- Update balances changed by any standard cost update between transactions
    IF (_prevCostmethod = 'S' AND _runningQty != 0) THEN
      PERFORM postValueintoInvBalance(pItemsiteid, costhist_date::date, _runningQty, _runningNn, costhist_oldcost, costhist_newcost )
      FROM costhist
      WHERE ((costhist_item_id=_r.itemsite_item_id)
        AND (costhist_date BETWEEN _prevDate AND _r.invhist_created)
        AND (costhist_type IN ('S','D')));
    END IF;

    -- Post transaction into inventory balance table
    PERFORM postIntoInvBalance(_r.invhist_id);

    _prevDate := _r.invhist_created;
    _prevCostmethod := _r.invhist_costmethod;
    _runningQty := _runningQty + _r.invhist_invqty * _r.sense;
    IF (_r.invhist_transtype = 'NN') THEN
      _runningNn := _runningNn + _r.invhist_invqty * -1;
    END IF;
    
  END LOOP;

  -- Update balances changed by any standard cost since last transaction
  IF (_prevCostmethod = 'S' AND _runningQty != 0) THEN
    PERFORM postValueintoInvBalance(pItemsiteid, costhist_date::date, _runningQty, _runningNn, costhist_oldcost, costhist_newcost )
    FROM costhist
    WHERE ((costhist_item_id=_r.itemsite_item_id)
      AND (costhist_date > _prevDate)
      AND (costhist_type IN ('S','D')));
  END IF;

  -- Forward update changes through all the balances
  PERFORM forwardupdateitemsite(pItemsiteId);
  
  RETURN 1;
END;

Function: public.buildsearchpath()

Returns: text

Language: PLPGSQL

buildSearchPath() examines the schemaord and pkghead tables to build a search path string. It ensures that public, api, and all enabled packages are included even if they are not listed in the schemaord table. It returns the constructed search_path but does not set it.

DECLARE
  _path   TEXT    := '';
  _schema TEXT;
  _seq    INTEGER;
BEGIN
  -- get the schemas as ordered by the administrator
  SELECT concatagg(quote_ident(schemaord_name) || ',') INTO _path
    FROM (SELECT schemaord_name
            FROM schemaord
            LEFT OUTER JOIN pkghead ON (schemaord_name=pkghead_name)
           WHERE (pkghead_id IS NULL
               OR (pkghead_id IS NOT NULL AND packageisenabled(pkghead_id)))
           ORDER BY schemaord_order
         ) AS xtspq;

  -- add others that we think/know we need
  -- TODO: is there a reason not to include public, api, or packages?
  FOR _schema, _seq IN
      SELECT pkghead_name AS schema, 0 AS seq
        FROM pkghead
       WHERE packageisenabled(pkghead_id)
      UNION ALL
      SELECT 'public', 1
      UNION ALL
      SELECT 'api', 2
      ORDER BY seq, schema
  LOOP
    IF (_path !~* (E'(^|\\W)' || _schema || E'(\\W|$)')) THEN
      _path := _path || ',' || quote_ident(_schema);
    END IF;
  END LOOP;

  -- remove extraneous spaces and commas
  _path = BTRIM(REGEXP_REPLACE(_path, '( ?, ?)+', ',', 'g'),
                ', ');

  RAISE DEBUG 'buildSearchPath() returning %', _path;

  RETURN _path;
END;

Function: public.calccashbudget(integer, integer, bpchar)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntId ALIAS FOR $1;
  pPeriodId ALIAS FOR $2;
  pInterval ALIAS FOR $3;
  _accntType CHAR;
  _currentBudget NUMERIC;
  _priorBudget NUMERIC;
  _result NUMERIC;
BEGIN

        SELECT accnt_type INTO _accntType
        FROM accnt
        WHERE (accnt_id=pAccntId);

        SELECT COALESCE(SUM(budget_amount),0) INTO _currentBudget
        FROM budget
        WHERE ((budget_accnt_id=pAccntId)
        AND (budget_period_id=pPeriodId));

        IF (pInterval='M') THEN
        SELECT (COALESCE(SUM(budget_amount),0)) INTO _priorBudget
                FROM budget,
                (SELECT COALESCE(pp.period_id,-1) AS prior_period_id
                        FROM period cp, period pp
                        WHERE ((cp.period_id=pPeriodId)
                        AND (cp.period_start > pp.period_start))
                        ORDER BY pp.period_start DESC LIMIT 1) AS data
                WHERE ((budget_accnt_id=pAccntId)
                AND (budget_period_id=prior_period_id));

                ELSE IF (pInterval='Q') THEN
                        SELECT (COALESCE(SUM(budget_amount),0)) INTO _priorBudget
                        FROM budget,
                                (SELECT COALESCE(pp.period_id,-1) AS prior_period_id
                                FROM period cp, period pp
                                WHERE ((cp.period_id=pPeriodId)
                                AND (cp.period_start > pp.period_start)
                                AND (pp.period_quarter=
                                CASE WHEN cp.period_quarter > 1 THEN
                                        cp.period_quarter - 1
                                ELSE 4 END)
                                AND (pp.period_start >= cp.period_start - interval '1 year'))
                                ORDER BY pp.period_start DESC LIMIT 1) AS data
                        WHERE ((budget_accnt_id=pAccntId)
                        AND (budget_period_id=prior_period_id));


                ELSE
                        SELECT (COALESCE(SUM(budget_amount),0)) INTO _priorBudget
                        FROM budget,
                                (SELECT pp.period_id AS prior_period_id
                        FROM period cp, period pp, yearperiod cy, yearperiod py
                        WHERE ((cp.period_id=pPeriodId)
                        AND (cp.period_yearperiod_id=cy.yearperiod_id)
                        AND (pp.period_yearperiod_id=py.yearperiod_id)
                        AND (cy.yearperiod_start > py.yearperiod_start))
                        ORDER BY pp.period_start DESC LIMIT 1) AS data
                        WHERE ((budget_accnt_id=pAccntId)
                        AND (budget_period_id=prior_period_id));

                END IF;
        END IF;

        IF _accntType='A' THEN
                _result := ((_priorBudget-_currentBudget) * -1 );

        ELSE IF (_accntType IN ('L','Q')) THEN
                _result := ((_priorBudget-_currentBudget) *-1);

        ELSE RETURN -1;
        END IF;
  END IF;


  RETURN _result;


END;

Function: public.calccmheadamt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT SUM(COALESCE(extprice, 0)) INTO _amount
  FROM cmhead JOIN creditmemoitem ON (cmhead_id=cmitem_cmhead_id)
  WHERE (cmhead_id=pCmheadid);

  RETURN _amount;

END;

Function: public.calccmheadtax(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  _headamount NUMERIC := 0;
  _itemamount NUMERIC := 0;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(SUM(taxhist_tax), 0) INTO _headamount
  FROM cmhead JOIN cmheadtax ON (taxhist_parent_id=cmhead_id)
  WHERE (cmhead_id=pCmheadid);

  SELECT SUM(COALESCE(tax, 0)) INTO _itemamount
  FROM cmhead JOIN creditmemoitem ON (cmhead_id=cmitem_cmhead_id)
  WHERE (cmhead_id=pCmheadid);

  _amount := _headamount + _itemamount;
  RETURN (_amount * -1.0);

END;

Function: public.calccobillamt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobillid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(round((cobill_qty * coitem_qty_invuomratio) *
                        (coitem_price / coitem_price_invuomratio), 2), 0) INTO _amount
  FROM cobill JOIN coitem ON (coitem_id=cobill_coitem_id)
  WHERE (cobill_id=pCobillid);

  RETURN _amount;

END;

Function: public.calccobilltax(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobillid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(calculateTax(cobmisc_taxzone_id,
                               cobill_taxtype_id,
                               cobmisc_shipdate,
                               cobmisc_curr_id,
                               calcCobillAmt(cobill_id)), 0) INTO _amount
  FROM cobill JOIN coitem ON (coitem_id=cobill_coitem_id)
              JOIN cobmisc ON (cobmisc_id=cobill_cobmisc_id)
  WHERE (cobill_id=pCobillid);

  RETURN _amount;

END;

Function: public.calccobmiscamt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT SUM(COALESCE(calcCobillAmt(cobill_id), 0)) INTO _amount
  FROM cobmisc JOIN cobill ON (cobmisc_id=cobill_cobmisc_id)
  WHERE (cobmisc_id=pCobmiscid);

  RETURN _amount;

END;

Function: public.calccobmisctax(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT SUM(
         COALESCE(calculateTax(cobmisc_taxzone_id,
                               cobill_taxtype_id,
                               cobmisc_shipdate,
                               cobmisc_curr_id,
                               COALESCE(round((cobill_qty * coitem_qty_invuomratio) * (coitem_price / coitem_price_invuomratio), 2), 0))
                 , 0)
            ) INTO _amount
  FROM cobmisc JOIN cobill ON (cobmisc_id=cobill_cobmisc_id)
               JOIN coitem ON (coitem_id=cobill_coitem_id)
  WHERE (cobmisc_id=pCobmiscid);

  RETURN _amount;

END;

Function: public.calcpendingarapplications(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  paropenid     ALIAS FOR $1;
  _arcreditsum  NUMERIC;
  _aropencurrid INTEGER;
  _cashrcptsum  NUMERIC;
  _sense INTEGER;

BEGIN
  SELECT aropen_curr_id,
    (CASE WHEN aropen_doctype IN ('I','D') THEN 1 ELSE -1 END) 
    INTO _aropencurrid, _sense
  FROM aropen
  WHERE (aropen_id=paropenid);

  SELECT SUM(currToCurr(cashrcpt_curr_id, _aropencurrid,
                        cashrcptitem_amount + cashrcptitem_discount, coalesce(cashrcpt_applydate, cashrcpt_distdate))) * _sense INTO _cashrcptsum
  FROM cashrcptitem, cashrcpt
  WHERE ((cashrcptitem_cashrcpt_id=cashrcpt_id)
    AND  (NOT cashrcpt_posted)
    AND  (NOT cashrcpt_void)
    AND  (cashrcptitem_aropen_id=paropenid)
    );

  SELECT SUM(currToCurr(arcreditapply_curr_id, _aropencurrid,
                        arcreditapply_amount, CURRENT_DATE)) INTO _arcreditsum
  FROM arcreditapply
  WHERE ((arcreditapply_target_aropen_id=paropenid)
    );

  RETURN round(COALESCE(_cashrcptsum, 0) + COALESCE(_arcreditsum, 0),2);
END;

Function: public.calcquoteamt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  _subtotal NUMERIC := 0;
  _tax NUMERIC := 0;
  _freight NUMERIC := 0;
  _misc NUMERIC := 0;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(SUM(ROUND((quitem_qtyord * quitem_qty_invuomratio) *
                            (quitem_price / quitem_price_invuomratio), 2)), 0) INTO _subtotal
  FROM quitem
  WHERE (quitem_quhead_id=pQuheadid);

  SELECT COALESCE(SUM(tax), 0) INTO _tax
  FROM ( SELECT ROUND(SUM(taxdetail_tax), 2) AS tax
         FROM tax JOIN calculateTaxDetailSummary('Q', pQuheadid, 'T') ON (taxdetail_tax_id=tax_id)
         GROUP BY tax_id ) AS data;

  SELECT COALESCE(quhead_freight, 0), COALESCE(quhead_misc, 0) INTO _freight, _misc
  FROM quhead
  WHERE (quhead_id=pQuheadid);

  _amount := _subtotal + _tax + _freight + _misc;

  RETURN _amount;

END;

Function: public.calcsalesorderamt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoheadid ALIAS FOR $1;
  _subtotal NUMERIC := 0;
  _tax NUMERIC := 0;
  _freight NUMERIC := 0;
  _misc NUMERIC := 0;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(SUM(ROUND((coitem_qtyord * coitem_qty_invuomratio) *
                            (coitem_price / coitem_price_invuomratio), 2)), 0) INTO _subtotal
  FROM coitem
  WHERE (coitem_cohead_id=pCoheadid)
    AND (coitem_status != 'X');

  SELECT COALESCE(SUM(tax), 0) INTO _tax
  FROM ( SELECT ROUND(SUM(taxdetail_tax), 2) AS tax
         FROM tax JOIN calculateTaxDetailSummary('S', pCoheadid, 'T') ON (taxdetail_tax_id=tax_id)
         GROUP BY tax_id ) AS data;

  SELECT COALESCE(cohead_freight, 0), COALESCE(cohead_misc, 0) INTO _freight, _misc
  FROM cohead
  WHERE (cohead_id=pCoheadid);

  _amount := _subtotal + _tax + _freight + _misc;

  RETURN _amount;

END;

Function: public.calcshipfreight(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadId ALIAS FOR $1;
  _result NUMERIC := 0;
  _order RECORD;
  _shipment RECORD;
  _weights RECORD;
  _price RECORD;
  _sales RECORD;
  _freightid INTEGER;
  _totalprice NUMERIC;
  _includepkgweight BOOLEAN := FALSE;
  _freight RECORD;
  _debug BOOLEAN := false;
BEGIN
  --Get shipment
  SELECT shiphead_order_id, shiphead_order_type, shiphead_freight 
  INTO _shipment
  FROM shiphead
  WHERE (shiphead_id=pShipheadId);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Shipment not found';
  END IF;

  IF (_shipment.shiphead_order_type = 'SO') THEN
  --Sales Orders
  
  --Get the order header information
    SELECT cust_id AS cust_id,
           custtype_id,
           custtype_code,
           shipto_id,
           shipto_num,
           cohead_orderdate AS orderdate,
           cohead_shipvia AS shipvia,
           shipto_shipzone_id AS shipzone_id,
           cohead_curr_id AS curr_id,
           currConcat(cohead_curr_id) AS currAbbr,
           cohead_calcfreight,
           cohead_freight
    INTO _order
    FROM cohead 
      JOIN custinfo ON (cust_id=cohead_cust_id)
      JOIN custtype ON (custtype_id=cust_custtype_id)
      LEFT OUTER JOIN shiptoinfo ON (shipto_id=cohead_shipto_id)
    WHERE (cohead_id=_shipment.shiphead_order_id);

    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Order not found';
    END IF;

    IF (_debug) THEN
      RAISE NOTICE 'cust_id = %', _order.cust_id;
      RAISE NOTICE 'custtype_id = %', _order.custtype_id;
      RAISE NOTICE 'shipto_id = %', _order.shipto_id;
      RAISE NOTICE 'shipto_num = %', _order.shipto_num;
      RAISE NOTICE 'orderdate = %', _order.orderdate;
      RAISE NOTICE 'shipvia = %', _order.shipvia;
      RAISE NOTICE 'shipzone_id = %', _order.shipzone_id;
      RAISE NOTICE 'curr_id = %', _order.curr_id;
      RAISE NOTICE 'currAbbr = %', _order.currAbbr;
      RAISE NOTICE 'calcfreight = %', _order.cohead_calcfreight;
      RAISE NOTICE 'freight = %', _order.cohead_freight;
    END IF;

    IF (NOT _order.cohead_calcfreight) THEN
      SELECT noNeg( _order.cohead_freight -
                    COALESCE((SELECT SUM(shiphead_freight)
                              FROM shiphead
                              WHERE (shiphead_order_id = _shipment.shiphead_order_id)
                                AND (shiphead_shipped='true')), 0) ) INTO _result;
      RETURN _result;
    END IF;

    SELECT fetchMetricBool('IncludePackageWeight') INTO _includepkgweight;

    --Calculate Sales Order freight
    --Get a list of aggregated weights from sites and
    --freight classes used on order lines
    FOR _weights IN
      SELECT CASE WHEN (_includePkgWeight) THEN
                        SUM(shipitem_qty * (item_prodweight + item_packweight))
                  ELSE  SUM(shipitem_qty * item_prodweight)
             END AS weight,
             itemsite_warehous_id, item_freightclass_id
      FROM shiphead
        JOIN shipitem ON (shipitem_shiphead_id=shiphead_id)
        JOIN coitem ON (shipitem_orderitem_id=coitem_id)
        JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
        JOIN item ON (item_id=itemsite_item_id)
      WHERE ( (shiphead_id=pShipheadId)
        AND   (item_freightclass_id IS NOT NULL) )
      GROUP BY itemsite_warehous_id, item_freightclass_id LOOP

    IF (_debug) THEN
      RAISE NOTICE '_weights.weight - %', _weights.weight;
      RAISE NOTICE '_weights.itemsite_warehous_id = %', _weights.itemsite_warehous_id;
      RAISE NOTICE '_weights.item_freightclass_id = %', _weights.item_freightclass_id;
    END IF;

    -- First get a sales price if any so we when we find other prices
    -- we can determine if we want that price or this price.
    --  Check for a Sale Price
    SELECT ipsfreight_id,
           CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                           ipsfreight_price, _order.orderdate)
                ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                (_weights.weight * ipsfreight_price), _order.orderdate)
           END AS price
           INTO _sales
    FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                    JOIN sale ON (sale_ipshead_id=ipshead_id)
    WHERE ( (ipsfreight_qtybreak <= _weights.weight)
      AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
      AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
      AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
      AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia))
      AND   (CURRENT_DATE BETWEEN sale_startdate AND sale_enddate) )
    ORDER BY ipsfreight_qtybreak DESC, price ASC
    LIMIT 1;

    IF (_debug) THEN
      IF (_sales.price IS NOT NULL) THEN
        RAISE NOTICE 'Sales Price found, %', _sales.price;
      END IF;
    END IF;

    --  Check for a Customer Shipto Price
    SELECT ipsfreight_id,
           CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                           ipsfreight_price, _order.orderdate)
                ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                (_weights.weight * ipsfreight_price), _order.orderdate)
           END AS price
           INTO _price
    FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    WHERE ( (ipsfreight_qtybreak <= _weights.weight)
      AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
      AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
      AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
      AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia))
      AND   (CURRENT_DATE BETWEEN ipshead_effective AND (ipshead_expires - 1))
      AND   (ipsass_cust_id=_order.cust_id)
      AND   (ipsass_shipto_id != -1)
      AND   (ipsass_shipto_id=_order.shipto_id) )
    ORDER BY ipsfreight_qtybreak DESC, price ASC
    LIMIT 1;

    IF (_debug) THEN
      IF (_price.price IS NOT NULL) THEN
        RAISE NOTICE 'Customer Shipto Price found, %', _price.price;
      END IF;
    END IF;

    IF (_price.price IS NULL) THEN
    --  Check for a Customer Shipto Pattern Price
      SELECT ipsfreight_id,
             CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                             ipsfreight_price, _order.orderdate)
                  ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                  (_weights.weight * ipsfreight_price), _order.orderdate)
             END AS price
             INTO _price
      FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                      JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
      WHERE ( (ipsfreight_qtybreak <= _weights.weight)
        AND   (CURRENT_DATE BETWEEN ipshead_effective AND (ipshead_expires - 1))
        AND   (ipsass_cust_id=_order.cust_id)
        AND   (COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0)
        AND   (_order.shipto_num ~ ipsass_shipto_pattern)
        AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
        AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
        AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
        AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia)) )
      ORDER BY ipsfreight_qtybreak DESC, price ASC
      LIMIT 1;

      IF (_debug) THEN
        IF (_price.price IS NOT NULL) THEN
          RAISE NOTICE 'Customer Shipto Pattern Price found, %', _price.price;
        END IF;
      END IF;

    END IF;

    IF (_price.price IS NULL) THEN
    --  Check for a Customer Price
      SELECT ipsfreight_id,
             CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                             ipsfreight_price, _order.orderdate)
                  ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                  (_weights.weight * ipsfreight_price), _order.orderdate)
             END AS price
             INTO _price
      FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                      JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
      WHERE ( (ipsfreight_qtybreak <= _weights.weight)
        AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
        AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
        AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
        AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia))
        AND   (CURRENT_DATE BETWEEN ipshead_effective AND (ipshead_expires - 1))
        AND   (ipsass_cust_id=_order.cust_id)
        AND   (COALESCE(LENGTH(ipsass_shipto_pattern), 0) = 0) )
      ORDER BY ipsfreight_qtybreak DESC, price ASC
      LIMIT 1;

      IF (_debug) THEN
        IF (_price.price IS NOT NULL) THEN
          RAISE NOTICE 'Customer Price found, %', _price.price;
        END IF;
      END IF;

    END IF;

    IF (_price.price IS NULL) THEN
    --  Check for a Customer Type Price
      SELECT ipsfreight_id,
             CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                             ipsfreight_price, _order.orderdate)
                  ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                  (_weights.weight * ipsfreight_price), _order.orderdate)
             END AS price
             INTO _price
      FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                      JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
      WHERE ( (ipsfreight_qtybreak <= _weights.weight)
        AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
        AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
        AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
        AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia))
        AND   (CURRENT_DATE BETWEEN ipshead_effective AND (ipshead_expires - 1))
        AND   (ipsass_custtype_id=_order.custtype_id) )
      ORDER BY ipsfreight_qtybreak DESC, price ASC
      LIMIT 1;

      IF (_debug) THEN
        IF (_price.price IS NOT NULL) THEN
          RAISE NOTICE 'Customer Type Price found, %', _price.price;
        END IF;
      END IF;

    END IF;

    IF (_price.price IS NULL) THEN
    --  Check for a Customer Type Pattern Price
      SELECT ipsfreight_id,
             CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, _order.curr_id,
                                                             ipsfreight_price, _order.orderdate)
                  ELSE currToCurr(ipshead_curr_id, _order.curr_id,
                                  (_weights.weight * ipsfreight_price), _order.orderdate)
             END AS price
             INTO _price
      FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                      JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
      WHERE ( (ipsfreight_qtybreak <= _weights.weight)
        AND   ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=_weights.itemsite_warehous_id))
        AND   ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=_weights.item_freightclass_id))
        AND   ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=_order.shipzone_id))
        AND   ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=_order.shipvia))
        AND   (CURRENT_DATE BETWEEN ipshead_effective AND (ipshead_expires - 1))
        AND   (COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0)
        AND   (_order.custtype_code ~ ipsass_custtype_pattern) )
      ORDER BY ipsfreight_qtybreak DESC, price ASC
      LIMIT 1;

      IF (_debug) THEN
        IF (_price.price IS NOT NULL) THEN
          RAISE NOTICE 'Customer Type Pattern Price found, %', _price.price;
        END IF;
      END IF;

    END IF;

    -- Select the lowest price  
    IF ( (_price.price IS NOT NULL) AND ((_sales.price IS NULL) OR (_price.price < _sales.price)) ) THEN
      _freightid := _price.ipsfreight_id;
      _totalprice := _price.price;
    ELSE
      IF ( (_sales.price IS NOT NULL) AND ((_price.price IS NULL) OR (_sales.price <= _price.price)) ) THEN
        _freightid := _sales.ipsfreight_id;
        _totalprice := _sales.price;
      END IF;
    END IF;

    -- Total
    IF (_freightid IS NOT NULL) THEN
      _result := _result + _totalprice;
    END IF;

    END LOOP;
    RETURN ROUND(_result,2);
  END IF;

  IF (_shipment.shiphead_order_type = 'TO') THEN
  --Transfer Orders
  
    SELECT noNeg( (SELECT SUM(toitem_freight) + tohead_freight
                   FROM tohead, toitem
                   WHERE (toitem_tohead_id=tohead_id)
                     AND (tohead_id = _shipment.shiphead_order_id)
                   GROUP BY tohead_freight) -
                  COALESCE((SELECT SUM(shiphead_freight)
                            FROM shiphead
                            WHERE (shiphead_order_id = _shipment.shiphead_order_id)
                              AND (shiphead_shipped='true')), 0) ) INTO _result;
    RETURN _result;
  END IF;

  RETURN _result;

END;

Function: public.calctotalslipqty(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTagid ALIAS FOR $1;
  _qty NUMERIC := 0;

BEGIN

  SELECT SUM(COALESCE(cntslip_qty, 0.0)) INTO _qty
  FROM cntslip
  WHERE (cntslip_cnttag_id=pTagid);

  RETURN _qty;

END;

Function: public.calculatefreightdetail(integer, integer, text, integer, integer, text, date, text, integer, character varying, integer, integer, numeric)

Returns: SET OF freightdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustId ALIAS FOR $1;
  pCustTypeId ALIAS FOR $2;
  pCustTypeCode ALIAS FOR $3;
  pShiptoId ALIAS FOR $4;
  pShipZoneId ALIAS FOR $5;
  pShiptoNum ALIAS FOR $6;
  pOrderDate ALIAS FOR $7;
  pShipVia ALIAS FOR $8;
  pCurrId ALIAS FOR $9;
  pCurrAbbr ALIAS FOR $10;
  pItemSiteWhsId ALIAS FOR $11;
  pItemFreightclassId ALIAS FOR $12;
  pWeight ALIAS FOR $13;

  _row freightData%ROWTYPE;
  _price RECORD;
  _sales RECORD;
  _freightid INTEGER;
  _totalprice NUMERIC;
  _asof DATE;
  _debug BOOLEAN := FALSE;

BEGIN

  --Get pricing effectivity metric
  IF (SELECT fetchMetricText('soPriceEffective') = 'OrderDate') THEN
    _asof := pOrderDate;
  ELSE
    _asof := CURRENT_DATE;
  END IF;

  _freightid := NULL;
  _totalprice := 0.0;

  IF (_debug) THEN
    RAISE NOTICE 'pWeight - %', pWeight;
    RAISE NOTICE 'pItemSiteWhsId = %', pItemSiteWhsId;
    RAISE NOTICE 'pItemFreightclassId = %', pItemFreightclassId;
  END IF;

-- First get a sales price if any so when we find other prices
-- we can determine if we want that price or this sales price.
--  Check for a Sale Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _sales
  FROM ipsfreight
  JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
  JOIN sale ON (sale_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia))
    AND (_asof BETWEEN sale_startdate AND sale_enddate)
    AND (pCustId IS NOT NULL) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_sales.price IS NOT NULL) THEN
      RAISE NOTICE 'Sales Price found, %', _sales.price;
    END IF;
  END IF;

--  Check for a Customer Shipto Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _price
  FROM ipsfreight
  JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
  JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia))
    AND (_asof BETWEEN ipshead_effective AND (ipshead_expires - 1))
    AND   (ipsass_shipto_id != -1)
    AND   (ipsass_shipto_id=pShiptoId) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_price.price IS NOT NULL) THEN
      RAISE NOTICE 'Customer Shipto Price found, %', _price.price;
    END IF;
  END IF;

  IF (_price.price IS NULL) THEN
--  Check for a Customer Shipto Pattern Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _price
  FROM ipsfreight
  JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
  JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND (_asof BETWEEN ipshead_effective AND (ipshead_expires - 1))
    AND (ipsass_cust_id=pCustId)
    AND (COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0)
    AND (pShiptoNum ~ ipsass_shipto_pattern)
    AND ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia)) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_price.price IS NOT NULL) THEN
      RAISE NOTICE 'Customer Shipto Pattern Price found, %', _price.price;
    END IF;
  END IF;

  END IF;

  IF (_price.price IS NULL) THEN
--  Check for a Customer Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _price
  FROM ipsfreight
  JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
  JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia))
    AND (_asof BETWEEN ipshead_effective AND (ipshead_expires - 1))
    AND (ipsass_cust_id=pCustId)
    AND (COALESCE(LENGTH(ipsass_shipto_pattern), 0) = 0) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_price.price IS NOT NULL) THEN
      RAISE NOTICE 'Customer Price found, %', _price.price;
    END IF;
  END IF;

  END IF;

  IF (_price.price IS NULL) THEN
--  Check for a Customer Type Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _price
  FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                  JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia))
    AND (_asof BETWEEN ipshead_effective AND (ipshead_expires - 1))
    AND (ipsass_custtype_id=pCustTypeId) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_price.price IS NOT NULL) THEN
      RAISE NOTICE 'Customer Type Price found, %', _price.price;
    END IF;
  END IF;

  END IF;

  IF (_price.price IS NULL) THEN
--  Check for a Customer Type Pattern Price
  SELECT ipsfreight_id,
    CASE WHEN (ipsfreight_type='F') THEN currToCurr(ipshead_curr_id, pCurrId,
        ipsfreight_price, pOrderDate)
      ELSE currToCurr(ipshead_curr_id, pCurrId,
        (pWeight * ipsfreight_price), pOrderDate)
    END AS price
  INTO _price
  FROM ipsfreight JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
                  JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE ( (ipsfreight_qtybreak <= pWeight)
    AND ((ipsfreight_warehous_id IS NULL) OR (ipsfreight_warehous_id=pItemSiteWhsId))
    AND ((ipsfreight_freightclass_id IS NULL) OR (ipsfreight_freightclass_id=pItemFreightclassId))
    AND ((ipsfreight_shipzone_id IS NULL) OR (ipsfreight_shipzone_id=pShipZoneId))
    AND ((ipsfreight_shipvia IS NULL) OR (ipsfreight_shipvia=pShipVia))
    AND (_asof BETWEEN ipshead_effective AND (ipshead_expires - 1))
    AND (COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0)
    AND (pCustTypeCode ~ ipsass_custtype_pattern) )
  ORDER BY ipsfreight_qtybreak DESC, price ASC
  LIMIT 1;

  IF (_debug) THEN
    IF (_price.price IS NOT NULL) THEN
      RAISE NOTICE 'Customer Type Pattern Price found, %', _price.price;
    END IF;
  END IF;

  END IF;

  -- Select the lowest price
  IF ( (_price.price IS NOT NULL) AND ((_sales.price IS NULL) OR (_price.price < _sales.price)) ) THEN
    _freightid := _price.ipsfreight_id;
    _totalprice := _price.price;
  ELSE
    IF ( (_sales.price IS NOT NULL) AND ((_price.price IS NULL) OR (_sales.price <= _price.price)) ) THEN
      _freightid := _sales.ipsfreight_id;
      _totalprice := _sales.price;
    END IF;
  END IF;

  IF (_debug) THEN
    RAISE NOTICE '_freightid = %', _freightid;
    RAISE NOTICE '_totalprice = %', _totalprice;
  END IF;

  -- Get information for the selected ipsfreight
  -- and return
  IF (_freightid IS NULL) THEN
    _row.freightdata_schedule := 'N/A';
    _row.freightdata_from := '';
    _row.freightdata_to := '';
    _row.freightdata_shipvia := '';
    _row.freightdata_freightclass := '';
    _row.freightdata_weight := 0;
    _row.freightdata_uom := '';
    _row.freightdata_price := 0;
    _row.freightdata_type := '';
    _row.freightdata_total := 0;
    _row.freightdata_currency := '';
    RETURN NEXT _row;
  ELSE
    SELECT ipshead_name AS freightdata_schedule,
      COALESCE(warehous_code, 'Any') AS freightdata_from,
      COALESCE(shipzone_name, 'Any') AS freightdata_to,
      COALESCE(ipsfreight_shipvia, 'Any') AS freightdata_shipvia,
      COALESCE(freightclass_code, 'Any') AS freightdata_freightclass,
      pWeight AS freightdata_weight,
      uom_name AS freightdata_uom,
      currToCurr(ipshead_curr_id, pCurrId, ipsfreight_price, pOrderDate) AS freightdata_price,
      CASE WHEN (ipsfreight_type='F') THEN 'Flat Rate'
        ELSE 'Per UOM'
      END AS freightdata_type,
      _totalprice AS freightdata_total,
      pCurrAbbr AS freightdata_currency
    INTO _row
    FROM ipsfreight
      JOIN ipshead ON (ipshead_id=ipsfreight_ipshead_id)
      LEFT OUTER JOIN uom ON (uom_item_weight)
      LEFT OUTER JOIN whsinfo ON (warehous_id=ipsfreight_warehous_id)
      LEFT OUTER JOIN shipzone ON (shipzone_id=ipsfreight_shipzone_id)
      LEFT OUTER JOIN freightclass ON (freightclass_id=ipsfreight_freightclass_id)
    WHERE (ipsfreight_id=_freightid);

    RETURN NEXT _row;
  END IF;

  RETURN;
END;

Function: public.calculatesubtax(integer, date, integer, numeric, integer)

Returns: SET OF taxdetail

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxCodeId ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pCurrId ALIAS FOR $3;
  pAmount ALIAS FOR $4;
  pLevel ALIAS FOR $5;
  _row taxdetail%ROWTYPE;
  _rownumber INTEGER := 1;
  _calc_tax Numeric :=0;
  _x RECORD;
  _y RECORD;

BEGIN
  FOR _x IN 

  SELECT tax_id, tax_code, tax_descrip, tax_basis_tax_id,
    taxrate_id, taxrate_percent, taxrate_curr_id, taxrate_amount,  
    taxclass_id, taxclass_code, COALESCE(taxclass_sequence,0) AS taxclass_sequence,
    curr_id, curr_abbr
  FROM tax, taxrate, taxclass, curr_symbol
  WHERE ((tax_id = taxrate_tax_id)
  AND (tax_taxclass_id = taxclass_id)
  AND (taxrate_curr_id = curr_id)
  AND (tax_basis_tax_id = pTaxCodeId)
  AND (pDate BETWEEN taxrate_effective AND taxrate_expires)
  AND (taxrate_curr_id = pCurrId))
  
  LOOP
    SELECT 
      ROUND((_x.taxrate_percent * pAmount + currToCurr(_x.curr_id, pCurrId, _x.taxrate_amount, pDate)), 6) 
    INTO _calc_tax;

    _row.taxdetail_tax_id = _x.tax_id;
    _row.taxdetail_tax_code = _x.tax_code;
    _row.taxdetail_tax_descrip = _x.tax_descrip;
    _row.taxdetail_tax_basis_tax_id = _x.tax_basis_tax_id ;
    _row.taxdetail_taxrate_percent = _x.taxrate_percent;
    _row.taxdetail_taxrate_amount = _x.taxrate_amount;
    _row.taxdetail_level = pLevel + 1;
    _row.taxdetail_taxclass_id = _x.taxclass_id ; 
    _row.taxdetail_taxclass_code = _x.taxclass_code;
    _row.taxdetail_taxclass_sequence = _x.taxclass_sequence;
    _row.taxdetail_tax = _calc_tax;
    _row.taxdetail_curr_id = _x.curr_id;
    _row.taxdetail_curr_abbr = _x.curr_abbr;

    RETURN NEXT _row;
    _rownumber := _rownumber + 1;

    FOR _y IN  
    SELECT * 
    FROM calculateSubTax( _x.tax_id, pDate, pCurrId, _calc_tax, pLevel + 1)
    LOOP
      _row.taxdetail_tax_id = _y.taxdetail_tax_id;
      _row.taxdetail_tax_code = _y.taxdetail_tax_code;
      _row.taxdetail_tax_descrip = _y.taxdetail_tax_descrip;
      _row.taxdetail_tax_basis_tax_id = _y.taxdetail_tax_basis_tax_id ;
      _row.taxdetail_taxrate_percent = _y.taxdetail_taxrate_percent;
      _row.taxdetail_taxrate_amount = _y.taxdetail_taxrate_amount;
      _row.taxdetail_level = _y.taxdetail_level + 1;
      _row.taxdetail_taxclass_id = _y.taxdetail_taxclass_id ; 
      _row.taxdetail_taxclass_code = _y.taxdetail_taxclass_code;
      _row.taxdetail_taxclass_sequence = _y.taxdetail_taxclass_sequence;
      _row.taxdetail_tax = _y.taxdetail_tax;
      _row.taxdetail_curr_id = _y.taxdetail_curr_id;
      _row.taxdetail_curr_abbr = _y.taxdetail_curr_abbr;
      
      RETURN NEXT _row;
      _rownumber := _rownumber + 1;

    END LOOP;

  END LOOP;

END;

Function: public.calculatetax(integer, integer, date, integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxZoneId ALIAS FOR  $1;
  pTaxTypeId ALIAS FOR  $2;
  pDate ALIAS FOR  $3;
  pCurrId ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  _tottax numeric := 0;  -- total tax
  
BEGIN

  SELECT COALESCE(ROUND(SUM(taxdetail_tax),6),0)
    INTO _tottax 
  FROM calculateTaxDetail(pTaxZoneId, pTaxTypeId, pDate, pCurrId, pAmount);

  RETURN _tottax;
  
END;

Function: public.calculatetaxdetail(integer, integer, date, integer, numeric)

Returns: SET OF taxdetail

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxZoneId ALIAS FOR  $1;
  pTaxTypeId ALIAS FOR  $2;
  pDate ALIAS FOR  $3;
  pCurrId ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  _row taxdetail%ROWTYPE;
  _x RECORD;
  _y RECORD;
  _z RECORD;
  _currcum numeric := 0;  -- Current cumulative tax
  _currseq numeric := 0;  -- Current group sequence
  _prevcum numeric := 0;  -- Previous cumulative tax
  _tax numeric := 0;      -- Calculated tax amount
  _taxbasis numeric := 0;  -- Used for calculating sub taxes

BEGIN

  IF ((COALESCE(pTaxTypeId,-1) = -1) OR (COALESCE(pTaxZoneId,-1) = -1)) THEN
    RETURN;
  END IF;

  SELECT DISTINCT
    COALESCE(taxass_taxzone_id, -1) AS taxzone_id,
    COALESCE(taxass_taxtype_id, -1) AS taxtype_id,
    taxass_tax_id,
    CASE
      WHEN ((taxass_taxzone_id IS NOT NULL) AND (taxass_taxtype_id IS NOT NULL)) THEN
        0
      WHEN ((taxass_taxzone_id IS NOT NULL) AND (taxass_taxtype_id IS NULL)) THEN
        1
      WHEN ((taxass_taxzone_id IS NULL) AND (taxass_taxtype_id IS NOT NULL)) THEN
        2
      ELSE
        3
    END AS sequence
    INTO _x
  FROM taxass
  WHERE  ((COALESCE(taxass_taxzone_id, pTaxZoneId, -1) = COALESCE(pTaxZoneId,-1))
  AND    (COALESCE(taxass_taxtype_id, pTaxTypeId, -1) = COALESCE(pTaxTypeId,-1)))
  ORDER BY sequence LIMIT 1;

  --Now loop through each tax detail record and return calculated result
  FOR _y IN
    SELECT  --the data required by taxdetail type.  Coalesce group sequence to 0 if no class.
    tax_id
    ,tax_code
    ,tax_descrip
    ,tax_basis_tax_id
    ,taxrate_percent
    ,taxrate_amount
    ,0 as taxdetail_level 
    ,taxclass_id
    ,taxclass_code
    ,COALESCE(taxclass_sequence, 0) AS taxclass_sequence
    ,0 as taxdetail_tax
    ,curr_id
    ,curr_abbr	
    FROM taxass, taxclass RIGHT OUTER JOIN tax  
      LEFT OUTER JOIN taxrate ON (taxrate_tax_id=tax_id)
    ON (tax_taxclass_id=taxclass_id),
    curr_symbol 
    WHERE 
    taxass_tax_id=tax_id
    AND taxrate_curr_id=curr_id
    AND COALESCE(taxass_taxzone_id, -1) = _x.taxzone_id
    AND COALESCE(taxass_taxtype_id, -1) = _x.taxtype_id
    AND pDate BETWEEN COALESCE(taxrate_effective, startoftime()) AND COALESCE(taxrate_expires, endoftime())
    ORDER BY COALESCE(taxclass_sequence, 0)
  LOOP
    -- If sequence has changed, cache the previous cumulative tax
    IF (_currseq != _x.sequence) THEN
      _prevcum := _currcum;
    END IF;

    -- Calculate the tax amount.  Convert currency for flat rate amounts
    SELECT 
    ROUND((_y.taxrate_percent * (pAmount + _prevcum) + currToCurr(_y.curr_id, pCurrId, _y.taxrate_amount, pDate)), 6) 
    INTO _tax
    FROM tax JOIN  taxrate ON (tax_id = taxrate_tax_id)
    WHERE (tax_id=_x.taxass_tax_id)
    AND (pDate BETWEEN COALESCE(taxrate_effective, startoftime()) AND COALESCE(taxrate_expires, endoftime()));

    --Map fields to _row

    _row.taxdetail_tax_id := _y.tax_id;
    _row.taxdetail_tax_code := _y.tax_code;
    _row.taxdetail_tax_descrip := _y.tax_descrip;
    _row.taxdetail_tax_basis_tax_id := _y.tax_basis_tax_id;
    _row.taxdetail_taxrate_percent := _y.taxrate_percent;
    _row.taxdetail_taxrate_amount := _y.taxrate_amount;
    _row.taxdetail_level := _y.taxdetail_level;
    _row.taxdetail_taxclass_id := _y.taxclass_id;
    _row.taxdetail_taxclass_code := _y.taxclass_code;
    _row.taxdetail_taxclass_sequence := _y.taxclass_sequence;
    _row.taxdetail_tax := _tax;
    _row.taxdetail_curr_id := _y.curr_id;
    _row.taxdetail_curr_abbr := _y.curr_abbr;
  
    RETURN NEXT _row;

    -- Increment cumulative balance and sequence number
    IF(_y.taxclass_sequence <> 0) THEN
      _currcum := _currcum + _tax;
    END IF;
    _currseq := _y.taxclass_sequence;

    -- Loop to Calculate sub taxes
    FOR _z IN
    SELECT *
    FROM calculateSubTax(_y.tax_id,pDate, pCurrId, _tax, 0)
    LOOP
     --Mapping of data
    _row.taxdetail_tax_id := _z.taxdetail_tax_id;
    _row.taxdetail_tax_code := _z.taxdetail_tax_code;
    _row.taxdetail_tax_descrip := _z.taxdetail_tax_descrip;
    _row.taxdetail_tax_basis_tax_id := _z.taxdetail_tax_basis_tax_id;
    _row.taxdetail_taxrate_percent := _z.taxdetail_taxrate_percent;
    _row.taxdetail_taxrate_amount := _z.taxdetail_taxrate_amount;
    _row.taxdetail_level := _z.taxdetail_level;
    _row.taxdetail_taxclass_id := _z.taxdetail_taxclass_id;
    _row.taxdetail_taxclass_code := _z.taxdetail_taxclass_code;
    _row.taxdetail_taxclass_sequence := _z.taxdetail_taxclass_sequence;
    _row.taxdetail_tax := _z.taxdetail_tax;
    _row.taxdetail_curr_id := _z.taxdetail_curr_id;
    _row.taxdetail_curr_abbr := _z.taxdetail_curr_abbr;

     RETURN NEXT _row;
     --Add to cumulative counter (_curcum)
     _currcum := _currcum + _z.taxdetail_tax ;

    END LOOP;

   END LOOP;
 
END;
 

Function: public.calculatetaxdetailline(text, integer)

Returns: SET OF taxdetail

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderType ALIAS FOR $1;
  pOrderId ALIAS FOR $2;
  _row taxdetail%ROWTYPE;
  _qry text;
  _totaltax numeric;
  _y RECORD;
  _table text;
  
BEGIN
   _totaltax=0.0;

   IF pOrderType = 'II' THEN
     _table := 'invcitemtax';
   ELSIF pOrderType = 'BI' THEN
     _table := 'cobilltax';
   ELSIF pOrderType = 'CI' THEN
     _table := 'cmitemtax';
   ELSIF pOrderType = 'VI' THEN
     _table := 'voitemtax';
   ELSIF pOrderType = 'TI' THEN
     _table := 'toitemtax';
   ELSIF pOrderType = 'AR' THEN
     _table := 'aropentax';
   ELSIF pOrderType = 'AP' THEN
     _table := 'apopentax';
   END IF;
     
   _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, COALESCE(taxhist_sequence,0) AS taxhist_sequence
            FROM taxhist 
             JOIN tax ON (taxhist_tax_id=tax_id) 
             JOIN pg_class ON (pg_class.oid=taxhist.tableoid) 
            WHERE ( (taxhist_parent_id = ' || pOrderId || ')
             AND (relname=''' || _table || ''') );';
    
   FOR _y IN  EXECUTE _qry
   LOOP
     _row.taxdetail_tax_id=_y.tax_id;
     _row.taxdetail_tax_code = _y.tax_code;
     _row.taxdetail_tax_descrip = _y.tax_descrip;
     _row.taxdetail_tax = _y.taxhist_tax;
     _row.taxdetail_level= 0 ;
     _row.taxdetail_taxclass_sequence= _y.taxhist_sequence;
     _totaltax = _totaltax + _y.taxhist_tax;
     RETURN NEXT _row;
   END LOOP;
 END;

Function: public.calculatetaxdetailsummary(text, integer, text)

Returns: SET OF taxdetail

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderType ALIAS FOR $1;
  pOrderId ALIAS FOR $2;
  pDisplayType ALIAS FOR $3;
  _row taxdetail%ROWTYPE;
  _qry text := '';
  _qry1 text;
  _totaltax numeric;
  _x RECORD;
  _y RECORD;
  _table text;
  
BEGIN
 _totaltax=0.0;
 IF pOrderType IN ('S','Q','RA','PO') THEN
   
   IF pOrderType = 'S' THEN
     _qry := 'SELECT ' || 'COALESCE(cohead_taxzone_id, -1) AS taxzone_id, cohead_orderdate AS order_date,
                cohead_curr_id AS curr_id, COALESCE(coitem_taxtype_id, -1) AS taxtype_id,
                ROUND((coitem_qtyord * coitem_qty_invuomratio) * (coitem_price / coitem_price_invuomratio),2) AS amount
              FROM cohead, coitem
              WHERE ( (coitem_cohead_id = ' || pOrderId || ')
               AND (' || 'cohead_id = coitem_cohead_id) 
               AND ( coitem_status != ''X'') )';
   ELSEIF  pOrderType = 'Q' THEN
     _qry := 'SELECT ' || 'COALESCE(quhead_taxzone_id, -1) AS taxzone_id, quhead_quotedate AS order_date,
                quhead_curr_id AS curr_id, COALESCE(quitem_taxtype_id, -1) AS taxtype_id, 
                ROUND((quitem_qtyord * quitem_qty_invuomratio) * (quitem_price / quitem_price_invuomratio),2) AS amount
              FROM quhead, quitem 
              WHERE ( (quitem_quhead_id = ' || pOrderId || ')
               AND (quhead_id = quitem_quhead_id) )'; 
   ELSEIF  pOrderType = 'RA' THEN
     _qry := 'SELECT ' || 'COALESCE(rahead_taxzone_id, -1) AS taxzone_id, rahead_authdate AS order_date,
                rahead_curr_id AS curr_id, COALESCE(raitem_taxtype_id, -1) AS taxtype_id, 
                ROUND((raitem_qtyauthorized * raitem_qty_invuomratio) * (raitem_unitprice / raitem_price_invuomratio),2) AS amount
              FROM rahead, raitem 
              WHERE ( (raitem_rahead_id = ' || pOrderId || ')
               AND (rahead_id = raitem_rahead_id) )';
   ELSEIF  pOrderType = 'PO' THEN
     _qry := 'SELECT ' || 'COALESCE(pohead_taxzone_id, -1) AS taxzone_id, pohead_orderdate AS order_date,
                pohead_curr_id AS curr_id, COALESCE(poitem_taxtype_id, -1) AS taxtype_id, 
                ROUND(poitem_qty_ordered * poitem_unitprice, 2) AS amount
              FROM pohead, poitem 
              WHERE ( (poitem_pohead_id = ' || pOrderId || ')
               AND (pohead_id = poitem_pohead_id) )'; 
  END IF;

  FOR _x IN EXECUTE _qry
  LOOP  
    _qry1 := 'SELECT * from calculatetaxdetail(' || _x.taxzone_id || ',' || _x.taxtype_id || ',''' || _x.order_date || ''',' || _x.curr_id  || ',' || _x.amount || ')';
    FOR _y IN  EXECUTE _qry1
    LOOP
      _row.taxdetail_tax_id=_y.taxdetail_tax_id;
      _row.taxdetail_tax_code = _y.taxdetail_tax_code;
      _row.taxdetail_tax_descrip = _y.taxdetail_tax_descrip;
      _row.taxdetail_tax = _y.taxdetail_tax;
      _row.taxdetail_level=_y.taxdetail_level;
      _row.taxdetail_taxclass_sequence= _y.taxdetail_taxclass_sequence;
      _totaltax = _totaltax + _y.taxdetail_tax;
      RETURN NEXT _row;
    END LOOP;
  END LOOP;

  IF pDisplayType = 'T' AND pOrderType <> 'PO' THEN
   IF pOrderType = 'S' THEN 
    _qry := 'SELECT COALESCE(cohead_taxzone_id, -1) AS taxzone_id, cohead_orderdate AS order_date,
               cohead_curr_id AS curr_id, cohead_freight AS freight
             FROM cohead WHERE cohead_id = ' || pOrderId ;
   ELSEIF  pOrderType = 'Q' THEN 
    _qry := 'SELECT COALESCE(quhead_taxzone_id, -1) AS taxzone_id, quhead_quotedate AS order_date,
               quhead_curr_id AS curr_id, COALESCE(quhead_freight,0) AS freight
             FROM quhead WHERE quhead_id = ' || pOrderId;
   ELSEIF pOrderType = 'RA' THEN
    _qry := 'SELECT COALESCE(rahead_taxzone_id, -1) AS taxzone_id, COALESCE(rahead_authdate,CURRENT_DATE) AS order_date,
               rahead_curr_id AS curr_id, COALESCE(rahead_freight,0) AS freight
             FROM rahead WHERE rahead_id = ' || pOrderId;
   END IF;

  FOR _x IN EXECUTE _qry
  LOOP
     _qry1 := 'SELECT * from calculatetaxdetail(' || _x.taxzone_id || ', getfreighttaxtypeid(),''' || _x.order_date || ''',' || _x.curr_id  || ',' || _x.freight || ')';
    FOR _y IN  EXECUTE _qry1
    LOOP
       _row.taxdetail_tax_id=_y.taxdetail_tax_id;
       _row.taxdetail_tax_code = _y.taxdetail_tax_code;
       _row.taxdetail_tax_descrip = _y.taxdetail_tax_descrip;
       _row.taxdetail_tax = _y.taxdetail_tax;
       _row.taxdetail_level=_y.taxdetail_level;
       _row.taxdetail_taxclass_sequence= _y.taxdetail_taxclass_sequence;
       _totaltax = _totaltax + _y.taxdetail_tax;
       RETURN NEXT _row;
     END LOOP;
   END LOOP;
  END IF;
  
 ELSEIF pOrderType IN ('I','B','CM', 'VO','TO') THEN
   IF (pOrderType='I') THEN
     _table := 'invcheadtax';
   ELSIF (pOrderType='B') THEN
     _table := 'cobmisctax';
   ELSIF (pOrderType='CM') THEN
     _table := 'cmheadtax';
   ELSIF (pOrderType='VO') THEN
     _table := 'voheadtax';
   ELSIF (pOrderType='TO') THEN
     _table := 'tohead';
   END IF;
   
   IF pOrderType = 'I' AND (pDisplayType IN ('L','T')) THEN
     _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
              FROM invchead, invcitemtax LEFT OUTER JOIN tax ON (taxhist_tax_id=tax_id)
               LEFT OUTER JOIN invcitem ON (invcitem_id=taxhist_parent_id) 
              WHERE invcitem_invchead_id = ' || pOrderId || ' 
               AND invchead_id = invcitem_invchead_id ';
   ELSIF pOrderType = 'B' AND (pDisplayType IN ('L','T')) THEN
    _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
             FROM cobmisc, cobilltax LEFT OUTER JOIN tax ON (taxhist_tax_id=tax_id)
             LEFT OUTER JOIN cobill ON (cobill_id=taxhist_parent_id)
             WHERE cobill_cobmisc_id = ' || pOrderId || ' 
             AND cobmisc_id = cobill_cobmisc_id ';
   ELSIF pOrderType = 'CM' AND (pDisplayType IN ('L','T')) THEN
    _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
             FROM cmhead, cmitemtax LEFT OUTER JOIN tax ON (taxhist_tax_id=tax_id)
             LEFT OUTER JOIN cmitem ON (cmitem_id=taxhist_parent_id)
             WHERE cmitem_cmhead_id = ' || pOrderId || ' 
             AND cmhead_id = cmitem_cmhead_id ';
   ELSIF pOrderType = 'VO' AND (pDisplayType IN ('L','T')) THEN
    _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
             FROM vohead, voitemtax LEFT OUTER JOIN tax ON (taxhist_tax_id=tax_id)
             LEFT OUTER JOIN voitem ON (voitem_id=taxhist_parent_id)
             WHERE voitem_vohead_id = ' || pOrderId || ' 
             AND vohead_id = voitem_vohead_id ';
   ELSIF pOrderType = 'TO' AND (pDisplayType IN ('L','T')) THEN
    _qry := 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
             FROM tohead, toitemtax LEFT OUTER JOIN tax ON (taxhist_tax_id=tax_id)
             LEFT OUTER JOIN toitem ON (toitem_id=taxhist_parent_id)
             WHERE toitem_tohead_id = ' || pOrderId || ' 
             AND tohead_id = toitem_tohead_id ';
   END IF;
   IF pDisplayType IN ('F','T') AND pOrderType <> 'VO' THEN
     IF (length(_qry) > 0) THEN
       _qry := _qry || ' UNION ALL ';
     END IF;
     _qry := _qry || 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
              FROM taxhist 
               JOIN tax ON (taxhist_tax_id=tax_id)
               JOIN pg_class ON (pg_class.oid=taxhist.tableoid)
              WHERE ( (taxhist_parent_id = ' || pOrderId || ') 
               AND (taxhist_taxtype_id=getfreighttaxtypeid())
               AND (relname=''' || _table || ''') )';
   END IF;
   IF pDisplayType IN ('A','T') THEN
     IF (length(_qry) > 0) THEN
       _qry := _qry || ' UNION ALL ';
     END IF;
     _qry := _qry || 'SELECT taxhist_tax_id as tax_id, tax_code, tax_descrip, taxhist_tax, taxhist_sequence
              FROM taxhist 
               JOIN tax ON (taxhist_tax_id=tax_id)
               JOIN pg_class ON (pg_class.oid=taxhist.tableoid)
              WHERE ( (taxhist_parent_id = ' || pOrderId || ') 
               AND (taxhist_taxtype_id=getadjustmenttaxtypeid())
               AND (relname=''' || _table || ''') )';

   END IF;
   FOR _y IN  EXECUTE _qry
   LOOP
     _row.taxdetail_tax_id=_y.tax_id;
     _row.taxdetail_tax_code = _y.tax_code;
     _row.taxdetail_tax_descrip = _y.tax_descrip;
     _row.taxdetail_tax = _y.taxhist_tax;
     _row.taxdetail_level= 0 ;
     _row.taxdetail_taxclass_sequence= COALESCE(_y.taxhist_sequence,0);
     _totaltax = _totaltax + _y.taxhist_tax;
     RETURN NEXT _row;
   END LOOP;
 END IF;
 END;

Function: public.calculatetaxhist(text, integer, integer, integer, date, integer, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTableName ALIAS FOR $1;
  pParentId  ALIAS FOR $2;
  pTaxZoneId ALIAS FOR $3;
  pTaxTypeId ALIAS FOR $4;
  pDate      ALIAS FOR $5;
  pCurrId    ALIAS FOR $6;
  pAmount    ALIAS FOR $7;
  _qry TEXT;
  
BEGIN
  IF (pTableName IS NULL) THEN
    RAISE EXCEPTION 'A table name is required to calculate tax history';
  ELSEIF (pParentId IS NULL) THEN
    RAISE EXCEPTION 'A parent ID is required to calculate tax history';
  ELSEIF (pDate IS NULL) THEN
    RAISE EXCEPTION 'A date is required to calculate tax history';
  ELSEIF (pAmount IS NULL) THEN
     RAISE EXCEPTION 'An amount is required to calculate tax history';
  END IF;

  -- Build a query that deletes any previous tax history for this document record
  _qry := 'DELETE FROM ' || pTableName || ' WHERE taxhist_parent_id = ' || pParentId || ' AND taxhist_taxtype_id <> getadjustmenttaxtypeid();';
  EXECUTE _qry;

  -- Next, build and execute query that inserts new rows.
  _qry := 'INSERT INTO ' || pTableName || ' (
             taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id, taxhist_basis,
             taxhist_basis_tax_id, taxhist_sequence, taxhist_percent, 
             taxhist_amount, taxhist_tax, taxhist_docdate)
           SELECT ' || pParentId || ',';
  IF (pTaxTypeId IS NULL) THEN
    _qry := _qry || 'NULL';
  ELSE
    _qry := _qry || pTaxTypeId;
  END If;
  _qry := _qry || ', taxdetail_tax_id,' || pAmount || ', 
             taxdetail_tax_basis_tax_id, taxdetail_taxclass_sequence, taxdetail_taxrate_percent,
             taxdetail_taxrate_amount, taxdetail_tax, ''' || pDate || '''
           FROM calculatetaxdetail(' || COALESCE(pTaxZoneId,-1) || ',' || COALESCE(pTaxTypeId,-1) ||',''' || pDate || ''',' || pCurrId || ',' || pAmount || ');';
  EXECUTE _qry;

  RETURN true;
END;

Function: public.calcvoucheramt(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoucherid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT SUM(COALESCE(vodist_amount, 0)) INTO _amount
  FROM vodist
  WHERE (vodist_vohead_id=pVoucherid);

  RETURN _amount;

END;

Function: public.calcvoucherfreight(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoucherid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT SUM(COALESCE(voitem_freight, 0)) INTO _amount
  FROM voitem
  WHERE (voitem_vohead_id=pVoucherid);

  RETURN _amount;

END;

Function: public.calcvouchertax(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoucherid ALIAS FOR $1;
  _amount NUMERIC := 0;

BEGIN

  SELECT COALESCE(calculateTax(vohead_taxzone_id,
                               vohead_taxtype_id,
                               vohead_docdate,
                               vohead_curr_id,
                               calcVoucherAmt(vohead_id)), 0) INTO _amount
  FROM vohead
  WHERE (vohead_id=pVoucherid);

  RETURN _amount;

END;

Function: public.calcwooperstartstub(integer, integer)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoId         ALIAS FOR $1;
  pBooitemSeqId ALIAS FOR $2;
  _result       DATE;
BEGIN

  IF ( SELECT ((metric_value='t') AND packageIsEnabled('xtmfg'))
         FROM metric
        WHERE(metric_name='Routings') ) THEN
    RETURN xtmfg.calcWooperStart(pWoId, pBooitemSeqId);
  END IF;
  RETURN null;
END;

Function: public.cancelbillingselection(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;

BEGIN

  IF ( ( SELECT cobmisc_posted
         FROM cobmisc
         WHERE (cobmisc_id=pCobmiscid) ) ) THEN
    RETURN -1;
  END IF;

  DELETE FROM cobill
  WHERE (cobill_cobmisc_id=pCobmiscid); 

  DELETE FROM cobmisc
  WHERE (cobmisc_id=pCobmiscid);

  RETURN 1;

END;

Function: public.changeaccountingperioddates(integer, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _check INTEGER;
  _r RECORD;

BEGIN

--  Check to make sure that the passed period is not closed
  IF ( ( SELECT period_closed
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

--  Check to make sure that the passed start date does not fall
--  into another period
  SELECT period_id INTO _check
  FROM period
  WHERE ( (pStartDate BETWEEN period_start AND period_end)
    AND (period_id <> pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to make sure that the passed end date does not fall
--  into another period
  SELECT period_id INTO _check
  FROM period
  WHERE ( (pEndDate BETWEEN period_start AND period_end)
    AND (period_id <> pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to make sure that the new passed start and end dates do not
--  orphan a posted G/L Transaction
  SELECT gltrans_id INTO _check
  FROM gltrans, period
  WHERE ( (gltrans_date BETWEEN period_start AND period_end)
   AND (gltrans_posted)
   AND (NOT (gltrans_date BETWEEN pStartDate AND pEndDate))
   AND (period_id=pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

--  Alter the start and end dates of the pass period
  UPDATE period
  SET period_start=pStartDate, period_end=pEndDate
  WHERE (period_id=pPeriodid);

--  Post any unposted G/L Transactions into the period
  FOR _r IN SELECT DISTINCT gltrans_sequence
            FROM gltrans
            WHERE ( (NOT gltrans_posted)
             AND (gltrans_date BETWEEN pStartDate AND pEndDate) ) LOOP
    PERFORM postIntoTrialBalance(_r.gltrans_sequence);
  END LOOP;

--  All done
  RETURN 1;

END;

Function: public.changeaccountingyearperioddates(integer, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _check INTEGER;
  _checkBool BOOLEAN;
  _r RECORD;

BEGIN

--  Check to make sure that the passed yearperiod is not closed
  IF ( ( SELECT yearperiod_closed
         FROM yearperiod
         WHERE (yearperiod_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

--  Check to make sure that the passed start date does not fall
--  into another yearperiod
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE ( (pStartDate BETWEEN yearperiod_start AND yearperiod_end)
    AND (yearperiod_id <> pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to make sure that the passed end date does not fall
--  into another yearperiod
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE ( (pEndDate BETWEEN yearperiod_start AND yearperiod_end)
    AND (yearperiod_id <> pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to make sure that the passed yearperiod is not closed
  IF ( ( SELECT (count(period_id) > 0)
         FROM period
         WHERE ((period_yearperiod_id=pPeriodid)
          AND (period_start < pStartDate OR period_end > pEndDate)) ) ) THEN
    RETURN -4;
  END IF;

--  Make sure that the passed start is prior to the end date
  SELECT (pStartDate > pEndDate) INTO _checkBool;
  IF (_checkBool) THEN
    RETURN -5;
  END IF;


--  Alter the start and end dates of the pass period
  UPDATE yearperiod
  SET yearperiod_start=pStartDate, yearperiod_end=pEndDate
  WHERE (yearperiod_id=pPeriodid);

--  All done
  RETURN 1;

END;

Function: public.changefkeypointers(text, text, integer, integer, text[], boolean)

Returns: integer

Language: PLPGSQL

Change the data in all tables with foreign key relationships so they point to the pSchema.pTable record with primary key pTargetId instead of the record with primary key pSourceId. Ignore any tables listed in pIgnore. If the final arg is TRUE, make a backup copy of the original data in the mrgundo table.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSchema       ALIAS FOR $1;
  pTable        ALIAS FOR $2;
  pSourceId     ALIAS FOR $3;
  pTargetId     ALIAS FOR $4;
  pIgnore       ALIAS FOR $5;
  _purge        BOOLEAN := COALESCE($6, FALSE);

  _counter      INTEGER := 0;
  _count1       INTEGER := 0;
  _fk           RECORD;
  _pk           TEXT[];

BEGIN
  -- for all foreign keys that point to pSchema.pTable
  FOR _fk IN
    EXECUTE 'SELECT fkeyns.nspname AS schemaname, fkeytab.relname AS tablename,
                    conkey, attname, typname
               FROM pg_constraint
               JOIN pg_class     basetab ON (confrelid=basetab.oid)
               JOIN pg_namespace basens  ON (basetab.relnamespace=basens.oid)
               JOIN pg_class     fkeytab ON (conrelid=fkeytab.oid)
               JOIN pg_namespace fkeyns  ON (fkeytab.relnamespace=fkeyns.oid)
               JOIN pg_attribute         ON (attrelid=conrelid AND attnum=conkey[1])
               JOIN pg_type              ON (atttypid=pg_type.oid)
              WHERE basetab.relname = ' || quote_literal(pTable)  || '
                AND basens.nspname  = ' || quote_literal(pSchema) || '
                AND fkeytab.relname NOT IN (''' || ARRAY_TO_STRING(pIgnore, ''', ''') || ''')'
  LOOP
    IF (ARRAY_UPPER(_fk.conkey, 1) > 1) THEN
      RAISE EXCEPTION 'Cannot change the foreign key in %.% that refers to %.% because the foreign key constraint has multiple columns. [xtuple: changefkeypointers, -1, %.%, %.%]',
        _fk.schemaname, _fk.tablename, pSchema, pTable,
        _fk.schemaname, _fk.tablename, pSchema, pTable;
    END IF;
    
    -- optionally make a backup copy of the data
    IF (NOT _purge) THEN
      -- determine the primary key column of the fkey table
      _pk := primaryKeyFields(_fk.schemaname, _fk.tablename);
      IF (ARRAY_UPPER(_pk, 1) > 1) THEN
        RAISE EXCEPTION 'Cannot change foreign key references in %.% because it has a composite primary key. Try setting the purge option. [xtuple: changefkeypointers, -4, %.%]',
                        _fk.schemaname, _fk.tablename, _fk.schemaname, _fk.tablename;
      END IF;

      -- make the backup copy
      EXECUTE 'INSERT INTO mrgundo (
                     mrgundo_schema,      mrgundo_table,
                     mrgundo_pkey_col,    mrgundo_pkey_id,
                     mrgundo_col,         mrgundo_value,      mrgundo_type,
                     mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
             ) SELECT ' || quote_literal(_fk.schemaname) || ', '
                        || quote_literal(_fk.tablename)  || ', '
                        || quote_literal(_pk[1])         || ', ' 
                        || _pk[1]                        || ', '
                        || quote_literal(_fk.attname)    || ', ' 
                        || _fk.attname                   || ', ' 
                        || quote_literal(_fk.typname)    || ', '
                        || quote_literal(pSchema)        || ', '
                        || quote_literal(pTable)         || ', '
                        || pTargetId                     || '
                 FROM ' || _fk.schemaname || '.' || _fk.tablename ||
              ' WHERE ('|| _fk.attname    || '=' || pSourceId || ');';
    END IF;

    -- actually change the foreign keys to point to the desired base table record
    EXECUTE 'UPDATE '  || _fk.schemaname || '.' || _fk.tablename ||
              ' SET '  || _fk.attname    || '=' || pTargetId ||
            ' WHERE (' || _fk.attname    || '=' || pSourceId || ');';

    GET DIAGNOSTICS _count1 = ROW_COUNT;
    _counter := _counter + _count1;
  END LOOP;

  RETURN _counter;
END;

Function: public.changepoitemduedate(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoitemid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  IF ( ( SELECT (poitem_status IN ('C'))
         FROM poitem
         WHERE (poitem_id=pPoitemid) ) ) THEN
    RETURN -1;
  END IF;

  UPDATE poitem
  SET poitem_duedate=pDate
  WHERE (poitem_id=pPoitemid);

  RETURN pPoitemid;

END;

Function: public.changepoitemqty(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoitemid ALIAS FOR $1;
  pQty ALIAS FOR $2;

BEGIN

  IF ( ( SELECT (poitem_status IN ('C'))
         FROM poitem
         WHERE (poitem_id=pPoitemid) ) ) THEN
    RETURN -1;
  END IF;

  UPDATE poitem
  SET poitem_qty_ordered=pQty
  WHERE (poitem_id=pPoitemid);

  RETURN pPoitemid;

END;

Function: public.changeprdate(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrid ALIAS FOR $1;
  pDueDate ALIAS FOR $2;

BEGIN

  UPDATE pr
  SET pr_duedate=pDueDate
  WHERE (pr_id=pPrid);

  RETURN 0;

END;

Function: public.changeprqty(integer, date)

Returns: integer

Language: PLPGSQL

DECLARE
  pPrid ALIAS FOR $1;
  pDueDate ALIAS FOR $2;

BEGIN

  UPDATE pr
  SET pr_duedate=pDueDate
  WHERE (pr_id=pPrid);

  RETURN 0;

END;

Function: public.changeprqty(integer, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrid ALIAS FOR $1;
  pQty ALIAS FOR $2;

BEGIN

  UPDATE pr
  SET pr_qtyreq=pQty
  WHERE (pr_id=pPrid);

  RETURN TRUE;

END;

Function: public.changepseudofkeypointers(text, text, text, integer, text, text, integer, text, text, boolean)

Returns: integer

Language: PLPGSQL

Change the data in pSchema.pTable with a pseudo-foreign key relationship to another (unnamed) table. Make pSchema.pTable point to the record with primary key pTargetId instead of the record with primary key pSourceId. pSchema.pTable cannot have a true foreign key relationship because it holds data that can point to any of several tables. The pType value in the pTypeCol column describes which table the data refer to (e.g. "T" may indicate that the current record refers to a "cntct"). If the final arg is TRUE, make a backup copy of the data in the mrgundo table.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSchema       ALIAS FOR $1;
  pTable        ALIAS FOR $2;
  pFkeyCol      ALIAS FOR $3;
  pSourceId     ALIAS FOR $4;
  pBaseSchema   ALIAS FOR $5;
  pBaseTable    ALIAS FOR $6;
  pTargetId     ALIAS FOR $7;
  pTypeCol      ALIAS FOR $8;
  pType         ALIAS FOR $9;
  _purge        BOOLEAN := COALESCE($10, FALSE);

  _counter      INTEGER := 0;
  _coltype      TEXT;
  _pk           TEXT[];

BEGIN
  IF (NOT _purge) THEN
    EXECUTE 'SELECT typname
               FROM pg_type
               JOIN pg_attribute ON (pg_type.oid=atttypid)
               JOIN pg_class     ON (attrelid=pg_class.oid)
               JOIN pg_namespace ON (relnamespace=pg_namespace.oid)
              WHERE (relname=' || quote_literal(pTable)   || ')
                AND (nspname=' || quote_literal(pSchema)  || ')
                AND (attname=' || quote_literal(pFkeyCol) || ')' INTO _coltype;

    _pk := primaryKeyFields(pSchema, pTable);
    IF (ARRAY_UPPER(_pk, 1) > 1) THEN
       RAISE EXCEPTION 'Cannot change pseudo-foreign key references in %.% because it has a composite primary key. Try setting the purge option. [xtuple: changepseudofkeypointers, -1, %.%',
                        pSchema, pTable, pSchema, pTable;
    END IF;

    EXECUTE 'INSERT INTO mrgundo (
                     mrgundo_schema,      mrgundo_table,
                     mrgundo_pkey_col,    mrgundo_pkey_id,
                     mrgundo_col,         mrgundo_value,      mrgundo_type,
                     mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
           ) SELECT ' || quote_literal(pSchema)     || ', '
                      || quote_literal(pTable)      || ', '
                      || quote_literal(_pk[1])      || ', ' 
                      || quote_ident(_pk[1])        || ', '
                      || quote_literal(pFkeyCol)    || ', ' 
                      || quote_ident(pFkeyCol)      || ', ' 
                      || quote_literal(_coltype)    || ', '
                      || quote_literal(pBaseSchema) || ', '
                      || quote_literal(pBaseTable)  || ', '
                      || pTargetId                  || '
               FROM '  || quote_ident(pSchema)  || '.' || quote_ident(pTable) || '
              WHERE (('|| quote_ident(pFkeyCol) || '=' || pSourceId || ')
                 AND ('|| quote_ident(pTypeCol) || '=' || quote_literal(pType) || '));';
  END IF;

  -- actually change the foreign keys to point to the desired base table record
  EXECUTE 'UPDATE '  || quote_ident(pSchema)  || '.' || quote_ident(pTable) ||
            ' SET '  || quote_ident(pFkeyCol) || '=' || pTargetId ||
          ' WHERE ((' || quote_ident(pFkeyCol) || '=' || pSourceId || ')
               AND (' || quote_ident(pTypeCol) || '=' || quote_literal(pType) || '));';

  GET DIAGNOSTICS _counter = ROW_COUNT;

  RETURN _counter;
END;

Function: public.changewodates(integer, date, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE 
  pWoid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pDueDate ALIAS FOR $3;
  changeChildren ALIAS FOR $4;
  _p RECORD;
  returnCode INTEGER;
  _vtemp NUMERIC;

BEGIN

  SELECT wo_status, wo_startdate, itemsite_warehous_id INTO _p
  FROM wo
  Inner Join itemsite on
      wo_itemsite_id=itemsite_id
  WHERE (wo_id=pWoid);

  IF (_p.wo_status = 'C') THEN 
    returnCode := 0;

  ELSIF (_p.wo_status IN ('R','I')) THEN
    INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                         evntlog_olddate, evntlog_newdate)
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'W', wo_id, itemsite_warehous_id, formatWoNumber(wo_id),
           wo_duedate, pDueDate
    FROM evntnot, evnttype, itemsite, item, wo
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (wo_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (evnttype_name='RWoDueDateRequestChange')
     AND (wo_id=pWoid) );

     returnCode := 0;

  END IF;
  
--  Reschedule operations if routings enabled
  IF (fetchMetricBool('Routings')) THEN

--    Reschedule wooper
    IF (fetchMetricBool('UseSiteCalendar')) THEN
      UPDATE xtmfg.wooper
      SET wooper_scheduled = calculatenextworkingdate(itemsite_warehous_id,DATE(pStartDate),
                             CAST(calculateworkdays(itemsite_warehous_id, DATE(wo_startdate), DATE(wooper_scheduled)) as INTEGER))
      FROM wo JOIN itemsite ON (wo_itemsite_id=itemsite_id)
      WHERE ( (wooper_wo_id=wo_id)
        AND   (wo_id=pWoid) );
    ELSE
      UPDATE xtmfg.wooper
      SET wooper_scheduled = (wooper_scheduled::DATE + (pStartDate - wo_startdate))
      FROM wo
      WHERE ( (wooper_wo_id=wo_id)
        AND   (wo_id=pWoid) );
    END IF;

--    Reschedule any womatl that is linked to wooper items
--    and is set to be scheduled with the wooper in question
    UPDATE womatl
    SET womatl_duedate=wooper_scheduled
    FROM xtmfg.wooper
    WHERE ( (womatl_schedatwooper)
     AND (womatl_wooper_id=wooper_id)
     AND (womatl_wo_id=pWoid) );

  END IF;

-- Reschedule any womatl that is not linked to wooper items
  UPDATE womatl
  SET womatl_duedate=pStartDate
  WHERE ( (NOT womatl_schedatwooper)
   AND (womatl_wo_id=pWoid) );

--  Reschedule the W/O
  UPDATE wo
  SET wo_startdate=pStartDate,
      wo_duedate=pDueDate
  WHERE (wo_id=pWoid);

--  Do the same for the children
  IF (changeChildren) THEN
    SELECT MAX(changeWoDates(wo_id, (pStartDate - itemsite_leadtime), pStartDate, TRUE)) INTO returnCode
    FROM wo, itemsite
    WHERE ( (wo_itemsite_id=itemsite_id)
     AND (wo_ordtype='W')
     AND (wo_ordid=pWoid) );
  END IF;

  IF (returnCode IS NULL) THEN
    returnCode := 0;
  END IF;

  RETURN returnCode;

END;

Function: public.changewoproject(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pPrjid ALIAS FOR $2;
  changeChildren ALIAS FOR $3;
  woStatus CHAR(1);
  _result INTEGER;

BEGIN

  SELECT wo_status INTO woStatus
  FROM wo
  WHERE (wo_id=pWoid);

  UPDATE wo
  SET wo_prj_id=pPrjid
  WHERE (wo_id=pWoid);

  IF (woStatus = 'E' AND changeChildren) THEN
    _result := ( SELECT MIN(changeWoProject(wo_id, pPrjid, TRUE))
                   FROM womatl, wo
                  WHERE ((womatl_itemsite_id=wo_itemsite_id)
                    AND (wo_ordtype='W')
                    AND (womatl_wo_id=pWoid)
                    AND (wo_ordid=pWoid)) );

    UPDATE pr SET pr_prj_id=pPrjid
      FROM womatl
     WHERE ((womatl_wo_id=pWoid)
       AND  (pr_order_type='W')
       AND  (pr_order_id=womatl_id));
  ELSE
    _result = 1;
  END IF;

  RETURN _result;
END;

Function: public.changewoqty(integer, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  changeChildren ALIAS FOR $3;
  _r RECORD;
  _result INTEGER := 1;

BEGIN

  SELECT wo_qtyord, wo_status, item_fractional INTO _r
  FROM wo JOIN itemsite ON (itemsite_id=wo_itemsite_id)
          JOIN item ON (item_id=itemsite_item_id)
  WHERE (wo_id=pWoid);

  IF (_r.wo_qtyord = pQty) THEN
    RETURN 0;
  END IF;

  IF (NOT _r.wo_status IN ('O','E','R','I')) THEN
    RETURN 1;
  END IF;

  IF (_r.wo_status IN ('R','I')) THEN
    INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number,
                         evntlog_oldvalue, evntlog_newvalue)
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'W', wo_id, itemsite_warehous_id, formatWoNumber(wo_id),
           wo_qtyord, pQty
    FROM evntnot, evnttype, itemsite, item, wo
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (wo_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (evnttype_name='RWoQtyRequestChange')
     AND (wo_id=pWoid) );

     _result = 0;
  END IF;

  UPDATE wo
  SET wo_qtyord=roundQty(_r.item_fractional, pQty)
  WHERE (wo_id=pWoid);

  UPDATE womatl
  SET womatl_qtyreq=(womatl_qtyfxd + wo_qtyord * womatl_qtyper) * (1 + womatl_scrap)
  FROM wo, itemsite
  WHERE ((womatl_wo_id=wo_id)
    AND  (womatl_itemsite_id=itemsite_id)
    AND  (wo_id=pWoid));

  IF (fetchMetricBool('Routings')) THEN

      UPDATE xtmfg.wooper
         SET wooper_rntime = CASE WHEN ((booitem_rnqtyper = 0) OR (booitem_invproduomratio = 0)) THEN 0
                                  WHEN (NOT booitem_rnrpt) THEN 0
                                  ELSE ( ( booitem_rntime /
                                           booitem_rnqtyper /
                                           booitem_invproduomratio ) * wo_qtyord )
                             END
        FROM xtmfg.booitem, wo
       WHERE ((wooper_wo_id=wo_id)
         AND  (wooper_booitem_id=booitem_id)
         AND  (wo_id=pWoid));
  END IF;

  IF (changeChildren) THEN
    _result := ( SELECT MIN(changeWoQty(wo_id, womatl_qtyreq, TRUE))
                 FROM womatl, wo
                 WHERE ((womatl_itemsite_id=wo_itemsite_id)
                  AND (wo_ordtype='W')
                  AND (womatl_wo_id=pWoid)
                  AND (wo_ordid=pWoid)) );
  END IF;

  RETURN _result;
END;

Function: public.characteristicstostring(text, integer, text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetType ALIAS FOR $1;
  pTargetId ALIAS FOR $2;
  pValKeySep ALIAS FOR $3;
  pPairSep ALIAS FOR $4;
  _string TEXT := '';
  _extra BOOLEAN := false;
  _r RECORD;
BEGIN
  FOR _r IN SELECT char_name, charass_value
              FROM charass, char
             WHERE ((charass_char_id=char_id)
               AND  (charass_target_type=pTargetType)
               AND  (charass_target_id=pTargetId)) LOOP
    IF(_extra) THEN
      _string := _string || pPairSep;
    END IF;
    _extra := true;

    _string := _string || _r.char_name || pValKeySep || _r.charass_value;
  END LOOP;

  RETURN _string;
END;

Function: public.checkcreditmemositeprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT cmitem_id
             FROM cmitem JOIN itemsite ON (itemsite_id=cmitem_itemsite_id)
            WHERE ( (cmitem_cmhead_id=pCmheadid)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checkdetailformatted(integer, integer)

Returns: SET OF checkdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckheadid ALIAS FOR $1;
  pMaxLines ALIAS FOR $2;
  _row checkdata%ROWTYPE;
  _checkhead RECORD;
  _checkdetail RECORD;
  _rowcount INTEGER := 0;
  _page INTEGER := 1;
  _docnumber TEXT := '';
  _docreference TEXT := '';
  _docdate TEXT := '';
  _docamount TEXT := '';
  _docdiscount TEXT := '';
  _docnetamount TEXT := '';
BEGIN

-- Check header information
  SELECT checkhead_number AS checknumber,
         INITCAP(spellAmount(checkhead_amount, curr_id)) AS checkwords,
         formatDate(checkhead_checkdate) AS checkdate,
         formatMoney(checkhead_amount) AS checkamount,
         curr_symbol AS checkcurrsymbol,
         curr_abbr AS checkcurrabbr,
         curr_name AS checkcurrname,
         CASE WHEN checkhead_recip_type = 'C' THEN (SELECT cust_name
                                                      FROM custinfo
                                                     WHERE cust_id=checkhead_recip_id)
              WHEN checkhead_recip_type = 'T' THEN (SELECT taxauth_name
                                                      FROM taxauth
                                                     WHERE taxauth_id=checkhead_recip_id)
              WHEN checkhead_recip_type = 'V' THEN
                                  COALESCE((SELECT vendaddr_name
                                              FROM vendaddrinfo
                                             WHERE((UPPER(vendaddr_code)='REMIT')
                                               AND (vendaddr_vend_id=checkhead_recip_id))),
                                           (SELECT vend_name
                                              FROM vendinfo
                                             WHERE(vend_id=checkhead_recip_id)))
         END AS checkpayto,
         formatAddr(CASE WHEN checkhead_recip_type = 'C' THEN
                                                  (SELECT cntct_addr_id
                                                   FROM cntct, custinfo
                                                    WHERE((cust_cntct_id=cntct_id)
                                                      AND (cust_id=checkhead_recip_id)))
                         WHEN checkhead_recip_type = 'T' THEN 
                                                  (SELECT taxauth_addr_id
                                                     FROM taxauth
                                                    WHERE(taxauth_id=checkhead_recip_id))
                         WHEN checkhead_recip_type = 'V' THEN
                                 COALESCE((SELECT vendaddr_addr_id
                                             FROM vendaddrinfo
                                            WHERE((UPPER(vendaddr_code)='REMIT')
                                              AND (vendaddr_vend_id=checkhead_recip_id))),
                                          (SELECT vend_addr_id
                                             FROM vendinfo
                                            WHERE(vend_id=checkhead_recip_id)))
                    END) AS checkaddress,
         checkhead_for AS checkmemo
    INTO _checkhead
    FROM checkhead, curr_symbol
   WHERE((checkhead_curr_id = curr_id)
     AND (checkhead_id=pCheckheadid) );
  IF (NOT FOUND) THEN
    RETURN;
  END IF;

  _row.checkdata_page := _page;
  _row.checkdata_checknumber := _checkhead.checknumber;
  _row.checkdata_checkwords := _checkhead.checkwords;
  _row.checkdata_checkdate := _checkhead.checkdate;
  _row.checkdata_checkamount := _checkhead.checkamount;
  _row.checkdata_checkcurrsymbol := _checkhead.checkcurrsymbol;
  _row.checkdata_checkcurrabbr := _checkhead.checkcurrabbr;
  _row.checkdata_checkcurrname := _checkhead.checkcurrname;
  _row.checkdata_checkpayto := _checkhead.checkpayto;
  _row.checkdata_checkaddress := _checkhead.checkaddress;
  _row.checkdata_checkmemo := _checkhead.checkmemo;

-- Check item details
  FOR _checkdetail IN 
  SELECT  --VOUCHER-------------
    1 AS ord,
    1 AS sequence_value,
    checkitem_invcnumber,
    checkitem_ponumber,
    formatMoney(checkitem_amount) AS docnetamount,
    'Invoice#: ' || vohead_invcnumber AS docnumber,
    formatDate(vohead_docdate) AS docdate,
    vohead_reference AS docreference,
    'Voucher: ' || checkitem_vouchernumber AS vouchernumber,
    formatMoney(apopen_amount) AS docamount,
    formatMoney(checkitem_discount) AS docdiscount
  FROM checkitem, vohead, apopen
  WHERE ((checkitem_checkhead_id=pCheckheadid)
    AND  (checkitem_vouchernumber = vohead_number)
    AND  (apopen_docnumber = checkitem_vouchernumber)
    AND  (apopen_doctype = 'V'))
  
  UNION
  
  SELECT --DEBIT MEMO -------------------------
    2 AS ord,
    1 AS sequence_value,
    checkitem_invcnumber,
    checkitem_ponumber,
    formatMoney(checkitem_amount) AS f_amount,
    'Debit Memo PO#: ' || checkitem_ponumber AS doc_number,
    ''  AS f_docdate,
    'Debit Memo: ' || checkitem_vouchernumber AS doc_reference,
    checkitem_vouchernumber AS vouchernumber,
    formatMoney(apopen_amount) AS amount,
    formatMoney(checkitem_discount) AS disc_cred
  FROM checkitem, apopen
  WHERE ((checkitem_checkhead_id=pCheckheadid)
    AND  (checkitem_vouchernumber = apopen_docnumber)
    AND  (apopen_doctype = 'D'))
  
  UNION
  
  SELECT --CREDITs--------------------------
    3 AS ord,
    1 AS sequence_value,
    checkitem_invcnumber,
    checkitem_ponumber,
    formatMoney(checkitem_amount) AS f_amount,
    'Invoice#: ' || vohead_invcnumber AS doc_number,
    formatDate(vohead_docdate) AS f_docdate,
    'Credit Applied: ' || apapply_source_doctype || ' ' ||
                          apapply_source_docnumber AS doc_reference,
    'Voucher ' || checkitem_vouchernumber AS vouchernumber,
    '' AS amount,
    formatMoney((apapply_amount)) AS disc_cred
  FROM checkitem, vohead, apapply
  WHERE ((checkitem_checkhead_id=pCheckheadid)
    AND  (checkitem_vouchernumber = vohead_number)
    AND  (apapply_target_docnumber = checkitem_vouchernumber ))
  
  UNION 
  
  SELECT --NON-VENDOR-----------------------
    4 AS ord,
    1 AS sequence_value,
    checkitem_invcnumber,
    checkitem_ponumber,
    formatMoney(checkitem_amount) AS f_amount,
    checkitem_invcnumber AS doc_number,
    formatDate(checkitem_docdate) AS f_docdate,
    '' AS doc_reference,
    '' AS vouchernumber,
    '' AS amount,
    '' AS disc_cred
  FROM checkhead LEFT OUTER JOIN
       checkitem ON (checkitem_checkhead_id=checkhead_id)
  WHERE ((checkhead_id=pCheckheadid) 
    AND  (checkhead_recip_type != 'V')) LOOP
    IF (_rowcount = pMaxLines) THEN
      _row.checkdata_docnumber := _docnumber;
      _row.checkdata_docreference := _docreference;
      _row.checkdata_docdate := _docdate;
      _row.checkdata_docamount := _docamount;
      _row.checkdata_docdiscount := _docdiscount;
      _row.checkdata_docnetamount := _docnetamount;
      RETURN NEXT _row;

-- update/reset some variables
      _rowcount = 0;
      _page := _page + 1;
      _docnumber := '';
      _docreference := '';
      _docdate := '';
      _docamount := '';
      _docdiscount := '';
      _docnetamount := '';

      _row.checkdata_page := _page;
      _row.checkdata_checknumber := _checkhead.checknumber;
      _row.checkdata_checkwords := 'VOID VOID PAGE '||_page||' OF CHECK #'||_checkhead.checknumber||' VOID VOID';
      _row.checkdata_checkdate := 'VOID VOID VOID';
      _row.checkdata_checkamount := 'VOID VOID VOID';
      --_row.checkdata_checkcurrsymbol := _checkhead.checkcurrsymbol;
      --_row.checkdata_checkcurrabbr := _checkhead.checkcurrabbr;
      --_row.checkdata_checkcurrname := _checkhead.checkcurrname;
      _row.checkdata_checkpayto := 'VOID VOID VOID';
      --_row.checkdata_checkaddress := _checkhead.checkaddress;
      _row.checkdata_checkmemo := 'VOID VOID PAGE '||_page||' OF CHECK #'||_checkhead.checknumber||' VOID VOID';
    END IF;

    _rowcount := _rowcount + 1;
    _docnumber := _docnumber || _checkdetail.docnumber || E'\n';
    _docreference := _docreference || _checkdetail.docreference || E'\n';
    _docdate := _docdate || _checkdetail.docdate || E'\n';
    _docamount := _docamount || _checkdetail.docamount || E'\n';
    _docdiscount := _docdiscount || _checkdetail.docdiscount || E'\n';
    _docnetamount := _docnetamount || _checkdetail.docnetamount || E'\n';
  END LOOP;

  _row.checkdata_docnumber := _docnumber;
  _row.checkdata_docreference := _docreference;
  _row.checkdata_docdate := _docdate;
  _row.checkdata_docamount := _docamount;
  _row.checkdata_docdiscount := _docdiscount;
  _row.checkdata_docnetamount := _docnetamount;

  RETURN NEXT _row;
  RETURN;
END;

Function: public.checkinvoicesiteprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT invcitem_id
             FROM invcitem
            WHERE ( (invcitem_invchead_id=pInvcheadid)
              AND   (invcitem_warehous_id <> -1)
              AND   (invcitem_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checkpositeprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT poitem_id
             FROM poitem, itemsite
            WHERE ( (poitem_pohead_id=pPoheadid)
              AND   (poitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
           UNION
           SELECT pohead_warehous_id
             FROM pohead
            WHERE ( (pohead_id=pPoheadid)
              AND   (pohead_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                  FROM usrsite
                                                 WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checkprivilege(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrivilege ALIAS FOR $1;
  _result TEXT;
BEGIN
  SELECT priv_id INTO _result
    FROM priv, grppriv, usrgrp
   WHERE((usrgrp_grp_id=grppriv_grp_id)
     AND (grppriv_priv_id=priv_id)
     AND (priv_name=pPrivilege)
     AND (usrgrp_username=getEffectiveXtUser()));
  IF (FOUND) THEN
    RETURN true;
  END IF;

  SELECT priv_id INTO _result
  FROM priv, usrpriv
  WHERE ((priv_id=usrpriv_priv_id)
  AND (priv_name=pPrivilege)
  AND (usrpriv_username=getEffectiveXtUser()));
  
  IF (FOUND) THEN
    RETURN true;
  ELSE
    RETURN false;
  END IF;
END;

Function: public.checkquotesiteprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;

BEGIN

  RETURN checkQuoteSitePrivs(pQuheadid, NULL);

END;

Function: public.checkquotesiteprivs(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  pWarehousid ALIAS FOR $2;
  _result   INTEGER := 0;

BEGIN

--  RAISE NOTICE 'checkQuoteSitePrivs, pQuheadid = %', pQuheadid;
--  RAISE NOTICE 'checkQuoteSitePrivs, pWarehousid = %', pWarehousid;

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF ( (NOT fetchUsrPrefBool('selectedSites')) AND (pWarehousid IS NULL) ) THEN
    RETURN true;
  END IF;

  IF (pWarehousid IS NULL) THEN
    SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM quitem JOIN itemsite ON (itemsite_id=quitem_itemsite_id)
                JOIN site() ON (warehous_id=itemsite_warehous_id)
    WHERE (quitem_quhead_id=pQuheadid);
  ELSE
    SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM quitem JOIN itemsite ON (itemsite_id=quitem_itemsite_id)
                JOIN site() ON (warehous_id=itemsite_warehous_id)
    WHERE ( (quitem_quhead_id=pQuheadid)
      AND   (itemsite_warehous_id=pWarehousid) );
  END IF;

  IF (_result > 0) THEN
    RETURN true;
  END IF;

  RETURN false;

END;

Function: public.checkrasiteprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pRaheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT raitem_id
             FROM raitem, itemsite
            WHERE ( (raitem_rahead_id=pRaheadid)
              AND   (raitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
           UNION
           SELECT raitem_id
             FROM raitem, itemsite
            WHERE ( (raitem_rahead_id=pRaheadid)
              AND   (raitem_coitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                  FROM usrsite
                                                 WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checkshipmentsiteprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT coitem_id
             FROM shipitem, coitem, itemsite
            WHERE ( (shipitem_shiphead_id=pShipheadid)
              AND   (coitem_id=shipitem_orderitem_id)
              AND   (coitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
           UNION
           SELECT cohead_warehous_id
             FROM shipitem, coitem, cohead
            WHERE ( (shipitem_shiphead_id=pShipheadid)
              AND   (coitem_id=shipitem_orderitem_id)
              AND   (cohead_id=coitem_cohead_id)
              AND   (cohead_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                  FROM usrsite
                                                 WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checksositeprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT coitem_id
             FROM coitem, itemsite
            WHERE ( (coitem_cohead_id=pSoheadid)
              AND   (coitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
           UNION
           SELECT cohead_warehous_id
             FROM cohead
            WHERE ( (cohead_id=pSoheadid)
              AND   (cohead_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                  FROM usrsite
                                                 WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.checkvouchersiteprivs(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoheadid ALIAS FOR $1;
  _check    BOOLEAN;
  _result   INTEGER;

BEGIN

  IF (NOT fetchMetricBool('MultiWhs')) THEN
    RETURN true;
  END IF;

  IF (NOT fetchUsrPrefBool('selectedSites')) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(COUNT(*), 0) INTO _result
    FROM ( SELECT voitem_id
             FROM voitem, poitem, itemsite
            WHERE ( (voitem_vohead_id=pVoheadid)
              AND   (poitem_id=voitem_poitem_id)
              AND   (poitem_itemsite_id=itemsite_id)
              AND   (itemsite_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                    FROM usrsite
                                                   WHERE (usrsite_username=getEffectiveXtUser()))) )
           UNION
           SELECT pohead_warehous_id
             FROM vohead, pohead
            WHERE ( (vohead_id=pVoheadid)
              AND   (pohead_id=vohead_pohead_id)
              AND   (pohead_warehous_id NOT IN (SELECT usrsite_warehous_id
                                                  FROM usrsite
                                                 WHERE (usrsite_username=getEffectiveXtUser()))) )
         ) AS data;
  IF (_result > 0) THEN
    RETURN false;
  END IF;

  RETURN true;
END;

Function: public.clearnumberissue(pnumber text, psequence integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  __seqiss	seqiss[];
  __newiss	seqiss[] := ARRAY[]::seqiss[];
  _i		INTEGER;
  _result	BOOLEAN := FALSE;
  _interval	TEXT := fetchMetricText('NumberIssueResetIntervalDays') || ' day';
  _number	INTEGER;
BEGIN
  -- get the sequence to update
  SELECT orderseq_seqiss INTO __seqiss
  FROM orderseq
  WHERE (orderseq_name=psequence);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Invalid orderseq_name %', psequence;
  END IF;

  IF(ARRAY_LENGTH(COALESCE(__seqiss,__newiss),1) IS NULL) THEN
    RETURN FALSE;
  END IF;

  -- build a new array sans the number we are releasing
  FOR _i IN 1..ARRAY_LENGTH(__seqiss,1)
  LOOP
    IF((__seqiss[_i]).seqiss_number = pnumber) THEN
      _result = TRUE;
    -- don't bother re-adding stale numbers
    ELSIF (now() - _interval::INTERVAL > (__seqiss[_i]).seqiss_time) THEN
      IF (_number IS NULL) THEN
        _number := (__seqiss[_i]).seqiss_number;
      ELSE 
        _number := LEAST((__seqiss[_i]).seqiss_number, _number);
      END IF;
    ELSE
      __newiss := __newiss || __seqiss[_i];
    END IF;
  END LOOP;

  -- update the order sequence with the result
  UPDATE orderseq SET
    orderseq_seqiss = __newiss
  WHERE (orderseq_name=psequence);

  -- reset to any cleared stale number
  IF(_number IS NOT NULL) THEN
    UPDATE orderseq SET
      orderseq_number = _number
    WHERE (orderseq_name=psequence);
  END IF;
  
  RETURN _result;
END;

Function: public.clearnumberissue(pnumber text, psequence text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _castpnumber  INTEGER;
BEGIN
  -- for now, order numbers in the database are text but usually
  -- string representations of integers. allow for the occasional non-integer.
  BEGIN
    _castpnumber  := CAST(pnumber AS INTEGER);
  EXCEPTION WHEN cannot_coerce OR
                 invalid_text_representation
  THEN
    RAISE DEBUG 'clearNumberIssue(%, %) received an unexpected pnumber',
                  psequence, pnumber;
    RETURN FALSE;
  END;

  RETURN clearNumberIssue(psequence, _castpnumber);
END;

Function: public.clearpayment(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApselectid ALIAS FOR $1;

BEGIN

  DELETE FROM apselect
  WHERE (apselect_id=pApselectid);

  RETURN 1;

END;

Function: public.closeaccountingperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  _r RECORD;
  _nextPeriodid INTEGER;
  _trialbalid INTEGER;
  _ending NUMERIC;
  _currYear INTEGER;
  _nextYear INTEGER;
BEGIN

--  Bypass error checking is this the the initial period
  IF ( NOT ( SELECT period_initial
             FROM period
             WHERE (period_id=pPeriodid) ) ) THEN

--  Check to make use that the period is not already closed
    IF ( ( SELECT period_closed
           FROM period
           WHERE (period_id=pPeriodid) ) ) THEN
      RETURN -1;
    END IF;

--  Make sure that the day before this period belongs to another period
    SELECT prev.period_id AS periodid, prev.period_closed AS closed INTO _r
    FROM period AS prev, period AS curr
    WHERE ( (prev.period_end = (curr.period_start - 1))
     AND (curr.period_id=pPeriodid) );
    IF (NOT FOUND) THEN
      RETURN -2;
    END IF;

--  Make sure that the previous period is closed
    IF (NOT _r.closed) THEN
      RETURN -3;
    END IF;

  END IF;

--  Make sure that there the next period is defined
  SELECT next.period_id INTO _nextPeriodid
  FROM period AS next, period AS curr
  WHERE ( (next.period_start = (curr.period_end + 1))
   AND (curr.period_id=pPeriodid) );
  IF (NOT FOUND) THEN
    RETURN -4;
  END IF;

--  Make sure that the user is not trying to prematurely close the Period
  IF ( ( SELECT (period_end >= CURRENT_DATE)
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -5;
  END IF;

  SELECT yearperiod_id INTO _currYear
    FROM yearperiod, period
   WHERE ((period_end BETWEEN yearperiod_start and yearperiod_end)
     AND  (period_id=pPeriodid));
  IF (NOT FOUND) THEN
    _currYear := -1;
  END IF;

  SELECT yearperiod_id INTO _nextYear
    FROM yearperiod, period
   WHERE ((period_end BETWEEN yearperiod_start and yearperiod_end)
     AND  (period_id=_nextPeriodid));
  IF (NOT FOUND) THEN
    RETURN -6;
  END IF;

--  Walk through the entire COA, calculating the ending balance and pushing
--  it to the beginning balance for the next period
  FOR _r IN SELECT accnt_id, accnt_type IN ('E', 'R') AS revexp,
                   trialbal_id, trialbal_beginning,
                   trialbal_credits, trialbal_debits
            FROM accnt LEFT OUTER JOIN trialbal ON ( (trialbal_accnt_id=accnt_id) AND (trialbal_period_id=pPeriodid) )
            ORDER BY accnt_id LOOP
    IF (_r.trialbal_id IS NULL) THEN
      _ending = 0;

      INSERT INTO trialbal
      ( trialbal_period_id, trialbal_accnt_id,
        trialbal_beginning, trialbal_ending, trialbal_dirty,
        trialbal_credits, trialbal_debits )
      VALUES
      ( pPeriodid, _r.accnt_id,
        0, 0, FALSE,
        0, 0 );
    ELSE
      _ending = (_r.trialbal_beginning - _r.trialbal_debits + _r.trialbal_credits);

      UPDATE trialbal
      SET trialbal_ending=_ending,
          trialbal_dirty = FALSE
      WHERE (trialbal_id=_r.trialbal_id);

      PERFORM forwardUpdateTrialBalance(_r.trialbal_id);
    END IF;

    IF (_r.revexp AND _currYear != _nextYear) THEN
      _ending := 0;
    END IF;

--  Find the trialbal record for the next period
    SELECT trialbal_id INTO _trialbalid
    FROM trialbal
    WHERE ( (trialbal_period_id=_nextPeriodid)
     AND (trialbal_accnt_id=_r.accnt_id) );
    IF (FOUND) THEN
      UPDATE trialbal
      SET trialbal_beginning = (_ending + trialbal_yearend),
          trialbal_ending = (_ending + trialbal_yearend - trialbal_debits + trialbal_credits)
      WHERE (trialbal_id=_trialbalid);
    ELSE
      INSERT INTO trialbal
      ( trialbal_period_id, trialbal_accnt_id,
        trialbal_beginning, trialbal_ending, trialbal_dirty,
        trialbal_credits, trialbal_debits )
      VALUES(_nextPeriodid, _r.accnt_id,
             _ending, _ending, TRUE,
             0, 0 );
    END IF;

  END LOOP;

--  Set the period_closed flag
  UPDATE period
  SET period_closed=TRUE
  WHERE (period_id=pPeriodid);

  RETURN pPeriodid;

END;

Function: public.closeaccountingyearperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pYearPeriodid ALIAS FOR $1;
  _result INTEGER;
BEGIN

--  Check to make sure that the yearperiod is not already closed
  IF ( ( SELECT yearperiod_closed
           FROM yearperiod
          WHERE (yearperiod_id=pYearPeriodid) ) ) THEN
    RETURN -1;
  END IF;

  IF ( ( SELECT (count(period_id) > 0)
           FROM period
          WHERE ((period_yearperiod_id=pYearPeriodid)
           AND (NOT period_closed)) ) ) THEN
    RETURN -10;
  END IF;

  IF ( ( SELECT (count(yearperiod_id) > 0)
           FROM yearperiod
          WHERE ((yearperiod_end< (
            SELECT yearperiod_end 
            FROM yearperiod 
            WHERE (yearperiod_id=pYearPeriodId))
          )
           AND (NOT yearperiod_closed)) ) ) THEN
    RETURN -11;
  END IF;

--  Should we check for a previous yearperiod existing already ?
--  If so then we should return -2 if one does not.

--  If we did the previous yearperiod we should check to make sure that
--  it is also closed. Returning -3 if it is not.

--  Make sure that the user is not trying to prematurely close the YearPeriod
  IF ( ( SELECT (yearperiod_end >= CURRENT_DATE)
           FROM yearperiod
          WHERE (yearperiod_id=pYearPeriodid) ) ) THEN
    RETURN -5;
  END IF;

--  Update the year end Retained Earnings
  SELECT updateRetainedEarnings(pYearPeriodid) INTO _result;
  IF (_result < 0) THEN
    RETURN _result;
  END IF;

  UPDATE yearperiod
    SET yearperiod_closed = TRUE
  WHERE yearperiod_id = pYearPeriodid;

  RETURN 0;

END;

Function: public.closepo(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;

BEGIN

  UPDATE poitem
  SET poitem_status='C'
  WHERE (poitem_pohead_id=pPoheadid);

-- _poitemTrigger will close pohead when the last poitem is closed
--  UPDATE pohead
--  SET pohead_status='C'
--  WHERE (pohead_id=pPoheadid);

  RETURN 1;

END;

Function: public.closewo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pPostMaterialVariances ALIAS FOR $2;

BEGIN
  
  RETURN closeWo(pWoid, pPostMaterialVariances, CURRENT_DATE);
END;

Function: public.closewo(integer, boolean, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pPostMaterialVariances ALIAS FOR $2;
  pTransDate ALIAS FOR $3;
  _woNumber TEXT;
  _check CHAR;
  _itemlocSeries INTEGER := 0;

BEGIN

  --If this is item type Job then we cannot close here
  SELECT itemsite_costmethod INTO _check
  FROM wo,itemsite
  WHERE ((wo_id=pWoid)
  AND (wo_itemsite_id=itemsite_id)
  AND (itemsite_costmethod = 'J'));
  IF (FOUND) THEN
    RAISE EXCEPTION 'Work orders for Job items are closed when all quantities are shipped';
  END IF;

  SELECT formatWoNumber(pWoid) INTO _woNumber;

-- If there are any tools issued on this job then we cannot close here
  IF ( SELECT (count(*) > 0)
       FROM womatl
       JOIN itemsite ON (womatl_itemsite_id=itemsite_id)
       JOIN item ON ((itemsite_item_id=item_id) AND (item_type='T'))
       WHERE ((womatl_wo_id=pWoid)
         AND  (womatl_qtyiss > 0)) ) THEN
    RAISE EXCEPTION 'All Tools must be returned before the W/O can be closed';
  END IF;

--  Distribute any remaining wo_wipvalue to G/L - debit Inventory Cost, credit WIP
  PERFORM insertGLTransaction( 'W/O', 'WO', _woNumber, ('Manufacturing Inventory Cost Variance for ' || item_number),
                               getPrjAccntId(wo_prj_id, costcat_wip_accnt_id), 
                               getPrjAccntId(wo_prj_id, costcat_invcost_accnt_id), -1,
                               COALESCE(wo_wipvalue, 0), pTransDate )
  FROM wo, itemsite, item, costcat
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (wo_id=pWoid) );

--  Distribute any remaining wo_brdvalue to G/L - debit Inventory Cost, credit WIP
  PERFORM insertGLTransaction( 'W/O', 'WO', _woNumber, ('Breeder Inventory Cost Variance for ' || item_number),
                               getPrjAccntId(wo_prj_id, costcat_wip_accnt_id),
                               CASE WHEN(itemsite_costmethod='A') THEN costcat_asset_accnt_id
                                    ELSE getPrjAccntId(wo_prj_id, costcat_invcost_accnt_id)
                               END,
                               -1,
                               COALESCE(wo_brdvalue, 0), pTransDate )
  FROM wo, itemsite, item, costcat
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (wo_id=pWoid) );

--  Don't bother with posting variances if the qtyrcv is 0 as
--  they are meaningless.
  IF ( ( SELECT wo_qtyrcv
         FROM wo
         WHERE (wo_id=pWoid) ) > 0 ) THEN

    IF (pPostMaterialVariances) THEN
--  Post womatl variances
    INSERT INTO womatlvar ( womatlvar_number, womatlvar_subnumber, womatlvar_posted,
        womatlvar_parent_itemsite_id, womatlvar_component_itemsite_id,
        womatlvar_qtyord, womatlvar_qtyrcv,
        womatlvar_qtyiss, womatlvar_qtyfxd, womatlvar_qtyper,
        womatlvar_scrap, womatlvar_wipscrap, womatlvar_bomitem_id,
        womatlvar_notes, womatlvar_ref )
      SELECT wo_number, wo_subnumber, pTransDate,
             wo_itemsite_id, womatl_itemsite_id,
             wo_qtyord, wo_qtyrcv,
             itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyiss),
             itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyfxd),
             itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyper),
             womatl_scrap,
             itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtywipscrap),
             womatl_bomitem_id,
             womatl_notes, womatl_ref             
      FROM wo, womatl, itemsite, item
      WHERE ((womatl_wo_id=wo_id)
       AND (womatl_itemsite_id=itemsite_id)
       AND (itemsite_item_id=item_id)
       AND (item_type <> 'T')      
       AND (wo_id=pWoid));
    END IF;
  END IF;

--  Delete any P/R's created for this W/O
  PERFORM deletePr('W', womatl_id)
  FROM womatl
  WHERE (womatl_wo_id=pWoid);

  UPDATE wo
  SET wo_wipvalue = 0, wo_brdvalue=0,
      wo_status='C'
  WHERE (wo_id=pWoid);

  RETURN 1;
END;

Function: public.cntct()

Returns: SET OF cntct

Language: PLPGSQL

A table function that returns Contact results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row cntct%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllContacts','ViewAllContacts','MaintainPersonalContacts','ViewPersonalContacts')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM cntct
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM cntct 
      WHERE cntct_owner_username = getEffectiveXtUser()
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.cntctdups(text, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: SET OF cntctdup

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSearchText ALIAS FOR $1;
  pSearchContactName ALIAS FOR $2;
  pSearchPhone ALIAS FOR $3;
  pSearchEmail ALIAS FOR $4;
  pSearchNumber ALIAS FOR $5;
  pSearchName ALIAS FOR $6;
  pShowInactive ALIAS FOR $7;
  pIgnoreBlanks ALIAS FOR $8;
  pIndentedDups ALIAS FOR $9;
  pCheckHnfc ALIAS FOR $10;
  pCheckFirst ALIAS FOR $11;
  pCheckMiddle ALIAS FOR $12;
  pCheckLast ALIAS FOR $13;
  pCheckSuffix ALIAS FOR $14;
  pCheckPhone ALIAS FOR $15;
  pCheckEmail ALIAS FOR $16;
  _cntct cntctdup%ROWTYPE;
  _cntctdup cntctdup%ROWTYPE;
  _rec RECORD;
  _operator TEXT := '';
  _clause TEXT;
  _qry  TEXT := '';
  _return BOOLEAN := true;
  _text TEXT;
  _first BOOLEAN := true;

BEGIN
  -- Validate
  IF (pIndentedDups AND NOT pCheckHnfc AND NOT pCheckFirst AND NOT pCheckMiddle AND 
      NOT pCheckLast AND NOT pCheckSuffix AND NOT pCheckEmail AND NOT pCheckPhone) THEN
    RETURN;
  END IF;

  _text = quote_literal(pSearchText);

  IF (pIndentedDups) THEN
    _qry := 'SELECT 
	-1 AS cntct_id,
	-1 AS cntct_crmacct_id,
	-1 AS cntct_addr_id,';
    IF (NOT pCheckFirst) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_first_name,';
    IF (NOT pCheckLast) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_last_name,';
    IF (NOT pCheckHnfc) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_honorific,';
    _qry := _qry || ' '''' AS cntct_initials,';
    _qry := _qry || ' NULL AS cntct_active,';
    IF (NOT pCheckPhone) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_phone,';
    IF (NOT pCheckPhone) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_phone2,';
    _qry := _qry || ' '''' AS cntct_fax,';
    IF (NOT pCheckEmail) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_email,';
    _qry := _qry || ' '''' AS cntct_webaddr,';
    _qry := _qry || ' '''' AS cntct_notes,';
    _qry := _qry || ' '''' AS cntct_title,';
    _qry := _qry || ' '''' AS cntct_number,';
    IF (NOT pCheckMiddle) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_middle,';
    IF (NOT pCheckSuffix) THEN
      _qry := _qry || ''''' AS ';
    END IF;
    _qry := _qry || ' cntct_suffix,';
    _qry := _qry || ' '''' AS cntct_owner_username,';
    _qry := _qry || ' '''' AS cntct_name,';
    _qry := _qry || ' '''' AS crmacct_number, ';
    _qry := _qry || ' '''' AS crmacct_name, ';
    _qry := _qry || ' NULL AS addr_id,
		NULL AS addr_active,
		'''' AS addr_line1,
		'''' AS addr_line2,
		'''' AS addr_line3,
		'''' AS addr_city,
		'''' AS addr_state,
		'''' AS addr_postalcode,
		'''' AS addr_country,
		'''' AS addr_notes,
		'''' AS addr_number,
		cntctdup_level FROM (';
  END IF;
    _clause := 'SELECT 
		cntct_id,
		cntct_crmacct_id,
		cntct_addr_id,
		UPPER(cntct_first_name) AS cntct_first_name,
		UPPER(cntct_last_name) AS cntct_last_name,
		UPPER(cntct_honorific) AS cntct_honorific,
		cntct_initials,
		cntct_active,
		cntct_phone,
		cntct_phone2,
		cntct_fax,
		UPPER(cntct_email) AS cntct_email,
		cntct_webaddr,
		cntct_notes,
		cntct_title,
		cntct_number,
		UPPER(cntct_middle) AS cntct_middle,
		UPPER(cntct_suffix) AS cntct_suffix,
		cntct_owner_username,
                cntct_name,
		crmacct_number, 
		crmacct_name,
		addr.*,
		0 AS cntctdup_level
             FROM cntct()
               LEFT OUTER JOIN crmacct ON (cntct_crmacct_id=crmacct_id) 
               LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id) 
	     WHERE ';

  IF (NOT pIndentedDups) THEN
    WHILE position('UPPER' in _clause) > 0
    LOOP
      _clause := regexp_replace(_clause, 'UPPER', '');
    END LOOP;
  END IF;

  _qry := _qry || _clause;
  	   
  IF (NOT pShowInactive) THEN
    _qry := _qry || ' cntct_active AND ';
  END IF;

  IF (pIgnoreBlanks) THEN
    _qry := _qry || ' (COALESCE(LENGTH(cntct_first_name || cntct_last_name),0) > 0) AND ';
  END IF;

    _qry := _qry || '(false ';

  IF (pSearchNumber) THEN
    _qry := _qry || ' OR (crmacct_number ~* ' || quote_literal(pSearchText) || ') ';
  END IF;

  IF (pSearchName) THEN
    _qry := _qry || ' OR (crmacct_name ~* ' || quote_literal(pSearchText) || ') ';
  END IF;

  IF (pSearchContactName) THEN
    _qry := _qry || ' OR (cntct_first_name || '' '' || cntct_last_name ~* ' || quote_literal(pSearchText) || ') ';
  END IF;
  
  IF (pSearchPhone) THEN
    _qry := _qry || ' OR (cntct_phone || '' '' || cntct_phone2 || '' '' || cntct_fax ~* ' || quote_literal(pSearchText) || ') ';
  END IF;

  IF (pSearchEmail) THEN
    _qry := _qry || ' OR (cntct_email ~* ' || quote_literal(pSearchText) || ') ';
  END IF;

  _qry := _qry || ' ) ';
  
  IF (pIndentedDups) THEN
    _qry := _qry || ') data';
    _clause := ' GROUP BY cntctdup_level';
    IF (pCheckHnfc) THEN
      _clause := _clause || ',cntct_honorific';
    END IF;
    IF (pCheckFirst) THEN
      _clause := _clause || ',cntct_first_name';
    END IF;
    IF (pCheckMiddle) THEN
      _clause := _clause || ',cntct_middle';
    END IF;
    IF (pCheckLast) THEN
      _clause := _clause || ',cntct_last_name';
    END IF;
    IF (pCheckSuffix) THEN
      _clause := _clause || ',cntct_suffix';
    END IF;
    IF (pCheckEmail) THEN
      _clause := _clause || ',cntct_email';
    END IF;
    IF (pCheckPhone) THEN
      _clause := _clause || ',cntct_phone';
      _clause := _clause || ',cntct_phone2';
    END IF;

    _qry := _qry || _clause; 

    _clause := ' HAVING(';
    IF (pCheckHnfc) THEN
      _clause := _clause || 'OR COUNT(cntct_honorific) > 1 ';
    END IF;
    IF (pCheckFirst) THEN
      _clause := _clause || 'OR COUNT(cntct_first_name) > 1 ';
    END IF;
    IF (pCheckMiddle) THEN
      _clause := _clause || 'OR COUNT(cntct_middle) > 1 ';
    END IF;
    IF (pCheckLast) THEN
      _clause := _clause || 'OR COUNT(cntct_last_name) > 1 ';
    END IF;
    IF (pCheckSuffix) THEN
      _clause := _clause || 'OR COUNT(cntct_suffix) > 1 ';
    END IF;
    IF (pCheckEmail) THEN
      _clause := _clause || 'OR COUNT(cntct_email) > 1 ';
    END IF;
    IF (pCheckPhone) THEN
      _clause := _clause || 'OR (COUNT(cntct_phone) > 1 AND LENGTH(cntct_phone) > 0) ';
      _clause := _clause || 'OR (COUNT(cntct_phone2) > 1 AND LENGTH(cntct_phone2) > 0) ';
    END IF;
    _clause := _clause || ') ';
    _clause := overlay(_clause placing '' from 9 for 2);

    IF (pCheckHnfc) THEN
      _clause := _clause || 'AND LENGTH(cntct_honorific) > 0 ';
    END IF;
    IF (pCheckFirst) THEN
      _clause := _clause || 'AND LENGTH(cntct_first_name) > 0  ';
    END IF;
    IF (pCheckMiddle) THEN
      _clause := _clause || 'AND LENGTH(cntct_middle) > 0  ';
    END IF;
    IF (pCheckLast) THEN
      _clause := _clause || 'AND LENGTH(cntct_last_name) > 0  ';
    END IF;
    IF (pCheckSuffix) THEN
      _clause := _clause || 'AND LENGTH(cntct_suffix) > 0  ';
    END IF;
    IF (pCheckEmail) THEN
      _clause := _clause || 'AND LENGTH(cntct_email) > 0  ';
    END IF;
    
    _qry := _qry || _clause;
  END IF;

  _qry := _qry || ' ORDER BY cntct_last_name, cntct_first_name;'; 

-- raise exception '%',_qry;
  FOR _cntct IN
    EXECUTE _qry
  LOOP

    RETURN NEXT _cntct;

    -- If duplicates, get duplicates
    IF (pIndentedDups) THEN
    
      _qry := 'SELECT                
                 cntct.*,
                 crmacct_number, 
                 crmacct_name,
                 addr.*,
                 1 AS cntctdup_level
               FROM cntct()
                 LEFT OUTER JOIN crmacct ON (cntct_crmacct_id=crmacct_id) 
                 LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
               WHERE (true) ';

      IF (pCheckHnfc) THEN
        _qry := _qry || ' AND (UPPER(cntct_honorific)=' || quote_literal(_cntct.cntct_honorific) || ')';
      END IF;

      IF (pCheckFirst) THEN
        _qry := _qry || ' AND (UPPER(cntct_first_name)=' || quote_literal(_cntct.cntct_first_name) || ')';
      END IF;

      IF (pCheckMiddle) THEN
        _qry := _qry || ' AND (UPPER(cntct_middle)=' || quote_literal(_cntct.cntct_middle) || ')';
      END IF;

      IF (pCheckLast) THEN
        _qry := _qry || ' AND (UPPER(cntct_last_name)=' || quote_literal(_cntct.cntct_last_name) || ')';
      END IF;

      IF (pCheckSuffix) THEN
        _qry := _qry || ' AND (UPPER(cntct_suffix)=' ||  quote_literal(_cntct.cntct_suffix) || ')';
      END IF;

      IF (pCheckPhone) THEN
        _qry := _qry || ' AND (cntct_phone=' || quote_literal(_cntct.cntct_phone)  || ')';
      END IF;

      IF (pCheckEmail) THEN
        _qry := _qry || ' AND (UPPER(cntct_email)=' || quote_literal(_cntct.cntct_email) || ')';
      END IF;

-- raise exception '%',_qry;
      FOR _cntctdup IN
        EXECUTE _qry
      LOOP
        RETURN NEXT _cntctdup;
      END LOOP;

    END IF;
    
  END LOOP;

  RETURN;
END;

Function: public.cntctmerge(integer, integer, boolean)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceCntctId ALIAS FOR $1;
  pTargetCntctId ALIAS FOR $2;
  pPurge ALIAS FOR $3;
  _fk		RECORD;
  _pk   	RECORD;
  _sel		RECORD;
  _seq  	INTEGER;
  _col		TEXT;
  _pkcol  	TEXT;
  _qry  	TEXT;
  _multi	BOOLEAN;

BEGIN
  -- Validate
  IF (pSourceCntctId IS NULL) THEN
    RAISE EXCEPTION 'Source contact id can not be null';
  ELSIF (pTargetCntctId IS NULL) THEN
    RAISE EXCEPTION 'Target contact id can not be null';
  ELSIF (pPurge IS NULL) THEN
    RAISE EXCEPTION 'Purge flag can not be null';
  END IF;
  
  -- Determine where this contact is used by analyzing foreign key linkages and update each
  FOR _fk IN
    SELECT pg_namespace.nspname AS schemaname, con.relname AS tablename, conkey AS seq, conrelid AS class_id 
    FROM pg_constraint, pg_class f, pg_class con, pg_namespace
    WHERE confrelid=f.oid
    AND conrelid=con.oid
    AND f.relname = 'cntct'
    AND con.relnamespace=pg_namespace.oid
    AND con.relname NOT IN ('cntctsel', 'cntctmrgd', 'mrghist','trgthist')
  LOOP
    -- Validate
    IF (ARRAY_UPPER(_fk.seq,1) > 1) THEN
      RAISE EXCEPTION 'Updates to tables where the contact is one of multiple foreign key columns is not supported. Error on Table: %',
        pg_namespace.nspname || '.' || con.relname;
    END IF;
    
    _seq := _fk.seq[1];

    -- Get the specific column name
    SELECT attname INTO _col
    FROM pg_attribute, pg_class
    WHERE ((attrelid=pg_class.oid)
    AND (pg_class.oid=_fk.class_id)
    AND (attnum=_seq));

    IF (NOT pPurge) THEN
    -- Cache what we're going to do so we can restore if need be.
    -- Start by determining the primary key column for this table.
      _multi := false;
      _qry := 'SELECT pg_attribute.attname AS key
               FROM pg_attribute, pg_class 
               WHERE pg_class.relnamespace = (
                 SELECT oid 
                 FROM pg_namespace 
                 WHERE pg_namespace.nspname = ''' || _fk.schemaname || ''') 
                AND  pg_class.oid IN (
                 SELECT indexrelid 
                 FROM pg_index 
                 WHERE indisprimary = true 
                  AND indrelid IN (
                    SELECT oid 
                    FROM pg_class 
                    WHERE lower(relname) = ''' || _fk.tablename || ''')) 
                AND pg_attribute.attrelid = pg_class.oid 
                AND pg_attribute.attisdropped = false 
               ORDER BY pg_attribute.attnum;';

      FOR _pk IN 
        EXECUTE _qry
      LOOP
        IF (_multi) THEN
          RAISE EXCEPTION 'Reference tables with composite primary keys not supported.  Try the merge and purge option.';
        END IF;
        _pkcol := _pk.key;
        _multi := true;
      END LOOP;

      -- Gather and store the history
      _qry := 'INSERT INTO mrghist 
               SELECT ' || pSourceCntctId || ', ''' 
                        || _fk.schemaname || '.' || _fk.tablename || ''', ''' 
                        || _pkcol || ''', ' 
                        || _pkcol || ', '''
                        || _col || ''' 
               FROM ' || _fk.schemaname || '.' || _fk.tablename || '
               WHERE (' || _col || '=' || pSourceCntctId || ');';
                   --           raise exception '%',_qry;
      EXECUTE _qry;
      
    END IF;

    -- Merge references
    _qry := 'UPDATE ' || _fk.schemaname || '.' || _fk.tablename ||
            ' SET ' || _col || '=' || pTargetCntctId ||
            ' WHERE (' || _col || '=' || pSourceCntctId || ');';
            
    EXECUTE _qry;
         
  END LOOP;

  -- Merge cases with no foreign key
  IF (NOT pPurge) THEN
    INSERT INTO mrghist 
    SELECT pSourceCntctId,
      'comment',
      'comment_id', 
      comment_id,
      'comment_source_id'
    FROM comment
    WHERE ((comment_source_id= pSourceCntctId)
    AND (comment_source='T'));

    INSERT INTO mrghist 
    SELECT pSourceCntctId,
      'docass',
      'docass_id', 
      docass_id,
      'docass_source_id'
    FROM docass
    WHERE ((docass_source_id= pSourceCntctId)
    AND (docass_source_type='T'));

    INSERT INTO mrghist 
    SELECT pSourceCntctId,
      'docass',
      'docass_id', 
      docass_id,
      'docass_target_id'
    FROM docass
    WHERE ((docass_target_id= pSourceCntctId)
    AND (docass_target_type='T'));

    INSERT INTO mrghist 
    SELECT pSourceCntctId,
      'vendinfo',
      'vend_id', 
      vend_id,
      'vend_cntct1_id'
    FROM vendinfo
    WHERE (vend_cntct1_id=pSourceCntctId);

    INSERT INTO mrghist 
    SELECT pSourceCntctId,
      'vendinfo',
      'vend_id', 
      vend_id,
      'vend_cntct2_id'
    FROM vendinfo
    WHERE (vend_cntct2_id=pSourceCntctId);

    IF (fetchMetricBool('EnableBatchManager') AND packageIsEnabled('xtbatch')) THEN
      INSERT INTO mrghist 
      SELECT pSourceCntctId,
      'xtbatch.emlassc',
      'emlassc_id', 
      emlassc_id,
      'emlassc_assc_id'
      FROM xtbatch.emlassc
      WHERE ((emlassc_assc_id= pSourceCntctId)
      AND (emlassc_type='T'));
    END IF;
  END IF;

  UPDATE comment
  SET comment_source_id = pTargetCntctId
  WHERE ((comment_source = 'T')
   AND (comment_source_id = pSourceCntctId));

  UPDATE docass
  SET docass_source_id = pTargetCntctId
  WHERE ((docass_source_type = 'T')
   AND (docass_source_id = pSourceCntctId));

  UPDATE docass
  SET docass_target_id = pTargetCntctId
  WHERE ((docass_target_type = 'T')
   AND (docass_target_id = pSourceCntctId));

  UPDATE vendinfo
  SET vend_cntct1_id = pTargetCntctId
  WHERE (vend_cntct1_id = pSourceCntctId);

  UPDATE vendinfo
  SET vend_cntct2_id = pTargetCntctId
  WHERE (vend_cntct2_id = pSourceCntctId);

  IF (fetchMetricBool('EnableBatchManager') AND packageIsEnabled('xtbatch')) THEN
    UPDATE xtbatch.emlassc
    SET emlassc_assc_id = pTargetCntctId
    WHERE ((emlassc_type = 'T')
     AND (emlassc_assc_id = pSourceCntctId));
  END IF;

  IF (NOT pPurge) THEN
  -- Record that this has been merged if not already
    IF (SELECT (COUNT(cntctmrgd_cntct_id) = 0) 
        FROM cntctmrgd
        WHERE (cntctmrgd_cntct_id=pSourceCntctId)) THEN
      INSERT INTO cntctmrgd VALUES (pSourceCntctId,false);
    END IF;
  END IF;

 -- Merge field detail to target
  SELECT * INTO _sel 
  FROM cntctsel 
    JOIN cntct ON (cntctsel_cntct_id=cntct_id)
  WHERE (cntctsel_cntct_id=pSourceCntctId);
  
  IF (FOUND) THEN
    IF (_sel.cntctsel_mrg_crmacct_id) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_crmacct_id', cntct_crmacct_id::text || '::integer'
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_crmacct_id=_sel.cntct_crmacct_id WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_addr_id) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_addr_id', cntct_addr_id::text || '::integer'
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_addr_id=_sel.cntct_addr_id WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_first_name) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_first_name', '''' || cntct_first_name || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_first_name=_sel.cntct_first_name WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_last_name) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_last_name', '''' || cntct_last_name || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_last_name=_sel.cntct_last_name WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_honorific) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_honorific', '''' || cntct_honorific || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_honorific=_sel.cntct_honorific WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_initials) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_initials', '''' || cntct_initials || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_initials=_sel.cntct_initials WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_phone) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_phone', '''' || cntct_phone || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_phone=_sel.cntct_phone WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_phone2) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_phone2', '''' || cntct_phone2 || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_phone2=_sel.cntct_phone2 WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_fax)  THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_fax', '''' || cntct_fax || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_fax=_sel.cntct_fax WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_email)  THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_email', '''' || cntct_email || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_email=_sel.cntct_email WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_webaddr) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_webaddr', '''' || cntct_webaddr || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_webaddr=_sel.cntct_webaddr WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_notes) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_notes', '''' || cntct_notes || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_notes=cntct_notes || '

      ' || _sel.cntct_notes WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_title) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_title', '''' || cntct_title || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_title=_sel.cntct_title WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_middle) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_middle', '''' || cntct_middle || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_middle=_sel.cntct_middle WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_suffix) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_suffix', '''' || cntct_suffix || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_suffix=_sel.cntct_suffix WHERE (cntct_id=pTargetCntctId);
    END IF;
    IF (_sel.cntctsel_mrg_owner_username) THEN
      IF (NOT pPurge) THEN
        INSERT INTO trgthist
        SELECT pSourceCntctId,pTargetCntctId,'cntct_owner_username', '''' || cntct_owner_username || ''''
        FROM cntct
        WHERE (cntct_id=pTargetCntctId);
      END IF;
      UPDATE cntct SET cntct_owner_username=_sel.cntct_owner_username WHERE (cntct_id=pTargetCntctId);
    END IF;
  ELSE
    RAISE EXCEPTION 'Source Contact not Found';
  END IF;

  -- Disposition source contact
  IF (pPurge) THEN
    DELETE FROM cntct WHERE cntct_id = pSourceCntctId;
  END IF;

  -- Deactivate contact
  UPDATE cntct SET cntct_active = false WHERE (cntct_id=pSourceCntctId);
  
  -- Clean up
  DELETE FROM cntctsel WHERE (cntctsel_cntct_id=pSourceCntctId);

  RETURN true;
END;

Function: public.cntctrestore(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntctId ALIAS FOR $1;
  _r RECORD;
  _qry TEXT;

BEGIN
  -- Validate
  SELECT * INTO _r FROM cntctmrgd WHERE (cntctmrgd_cntct_id=pCntctId);
  IF (NOT FOUND) THEN
    RETURN false;
  END IF;
  
  -- Gather the list of affected records
  FOR _r IN
    SELECT * FROM mrghist
    WHERE (mrghist_cntct_id=pCntctId)
  LOOP
    -- Restore the old references
    _qry := 'UPDATE ' || _r.mrghist_table ||
            ' SET ' || _r.mrghist_cntct_col || '=' || pCntctId ||
            ' WHERE (' || _r.mrghist_pkey_col || '=' || _r.mrghist_pkey_id || ');';
    
   EXECUTE _qry;
         
  END LOOP;

  -- Gather the list of affected fields
  FOR _r IN
    SELECT * FROM trgthist
    WHERE (trgthist_src_cntct_id=pCntctId)
  LOOP
    -- Restore the old values
    _qry := 'UPDATE cntct
              SET ' || _r.trgthist_col || '=' || _r.trgthist_value ||
            ' WHERE (cntct_id=' || _r.trgthist_trgt_cntct_id || ');';
    
   EXECUTE _qry;
         
  END LOOP;

  -- Clean up
  UPDATE cntct SET cntct_active=true WHERE (cntct_id=pCntctId);
  DELETE FROM mrghist WHERE (mrghist_cntct_id=pCntctId);
  DELETE FROM trgthist WHERE (trgthist_src_cntct_id=pCntctId);
  DELETE FROM cntctmrgd WHERE (cntctmrgd_cntct_id=pCntctId);

  RETURN true;

END;

Function: public.cntctselect(integer, boolean)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntctId ALIAS FOR $1;
  pTarget ALIAS FOR $2;

BEGIN
  -- If target, delete any other targets
  IF (pTarget) THEN
    DELETE FROM cntctsel WHERE cntctsel_target;
  END IF;
  
  -- Delete any previous selection of this contact
  DELETE FROM cntctsel WHERE cntctsel_cntct_id=pCntctId;

  -- Add this contact in appropriate selection state
  INSERT INTO cntctsel VALUES (pCntctId,pTarget);

  RETURN true;
END;

Function: public.cntctselectcol(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntctId ALIAS FOR $1;
  pColNumber ALIAS FOR $2;

BEGIN

  IF (pColNumber = 2 OR pColNumber = 3) THEN
    UPDATE cntctsel SET cntctsel_mrg_crmacct_id=false WHERE (cntctsel_mrg_crmacct_id AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_crmacct_id=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 4) THEN
    UPDATE cntctsel SET cntctsel_mrg_honorific=false WHERE (cntctsel_mrg_honorific AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_honorific=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 5) THEN
    UPDATE cntctsel SET cntctsel_mrg_first_name=false WHERE (cntctsel_mrg_first_name AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_first_name=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 6) THEN
    UPDATE cntctsel SET cntctsel_mrg_middle=false WHERE (cntctsel_mrg_middle AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_middle=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 7) THEN
    UPDATE cntctsel SET cntctsel_mrg_last_name=false WHERE (cntctsel_mrg_last_name AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_last_name=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 8) THEN
    UPDATE cntctsel SET cntctsel_mrg_suffix=false WHERE (cntctsel_mrg_suffix AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_suffix=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 9) THEN
    UPDATE cntctsel SET cntctsel_mrg_initials=false WHERE (cntctsel_mrg_initials AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_initials=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 10) THEN
    UPDATE cntctsel SET cntctsel_mrg_phone=false WHERE (cntctsel_mrg_phone AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_phone=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 11) THEN
    UPDATE cntctsel SET cntctsel_mrg_phone2=false WHERE (cntctsel_mrg_phone2 AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_phone2=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 12) THEN
    UPDATE cntctsel SET cntctsel_mrg_fax=false WHERE (cntctsel_mrg_fax AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_fax=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 13) THEN
    UPDATE cntctsel SET cntctsel_mrg_email=false WHERE (cntctsel_mrg_email AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_email=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 14) THEN
    UPDATE cntctsel SET cntctsel_mrg_webaddr=false WHERE (cntctsel_mrg_webaddr AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_webaddr=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 15) THEN
    UPDATE cntctsel SET cntctsel_mrg_title=false WHERE (cntctsel_mrg_title AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_title=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 16) THEN
    UPDATE cntctsel SET cntctsel_mrg_owner_username=false WHERE (cntctsel_mrg_owner_username AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_owner_username=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber = 17) THEN
    UPDATE cntctsel SET cntctsel_mrg_notes=false WHERE (cntctsel_mrg_notes AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_notes=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  ELSIF (pColNumber >= 18) THEN
    UPDATE cntctsel SET cntctsel_mrg_addr_id=false WHERE (cntctsel_mrg_addr_id AND cntctsel_cntct_id != pCntctId);
    UPDATE cntctsel SET cntctsel_mrg_addr_id=true WHERE (cntctsel_cntct_id = pCntctId);
    RETURN true;
  END IF;

  RETURN false;
END;

Function: public.cntctused(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntctId ALIAS FOR $1;
  _fk RECORD;
  _r RECORD;
  _seq INTEGER;
  _col TEXT;
  _qry TEXT;

BEGIN
  -- Determine where this contact is used by analyzing foreign key linkages
  -- but ignore child tables and those with impermanent relationships
  FOR _fk IN
    SELECT pg_namespace.nspname AS schemaname, con.relname AS tablename, conkey AS seq, conrelid AS class_id 
    FROM pg_constraint, pg_class f, pg_class con, pg_namespace
    WHERE confrelid=f.oid
    AND conrelid=con.oid
    AND f.relname = 'cntct'
    AND con.relnamespace=pg_namespace.oid
    AND con.relname NOT IN ('cntctaddr', 'cntctdata', 'cntcteml',
                            'cohead',    'pohead',    'quhead',   'tohead',
                            'cntctsel',  'cntctmrgd', 'mrghist',  'trgthist')
  LOOP
    -- Validate
    IF (ARRAY_UPPER(_fk.seq,1) > 1) THEN
      RAISE EXCEPTION 'Cannot check dependencies when the contact is one of multiple foreign key columns (%.%) [xtuple: fkeycheck, -1, %, %]',
        _fk.nspname, _fk.relname, _fk.nspname, _fk.relname;
    END IF;
    
    _seq := _fk.seq[1];

    -- Get the specific column name
    SELECT attname INTO _col
    FROM pg_attribute, pg_class
    WHERE ((attrelid=pg_class.oid)
    AND (pg_class.oid=_fk.class_id)
    AND (attnum=_seq));

    -- See if there are dependencies
    _qry := 'SELECT * 
            FROM ' || _fk.schemaname || '.' || _fk.tablename || '
            WHERE ('|| _col || '=' || pCntctId || ');';

    FOR _r IN 
      EXECUTE _qry
    LOOP
      RETURN true;
    END LOOP;
         
  END LOOP;

  RETURN false;

END;

Function: public.coheadstatecolor(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoheadId	ALIAS FOR $1;
  _shipheadid	INTEGER;
  _result	TEXT := '';

BEGIN
  
  IF (pCoheadid IS NULL) THEN
    RAISE EXCEPTION 'Customer Id is required.';
  END IF;
  
  SELECT 
    shiphead_id INTO _shipheadid
  FROM cohead
    JOIN shiphead ON ((shiphead_order_id=cohead_id)
                  AND (shiphead_order_type='SO'))
    JOIN shipitem ON (shiphead_id=shipitem_shiphead_id)
  WHERE ((cohead_id=pCoheadId)
    AND (NOT shipitem_invoiced))
  ORDER BY shiphead_id DESC
  LIMIT 1;

  IF (FOUND) THEN
    SELECT 
      CASE 
        WHEN ((shiphead_shipped) 
         AND (COALESCE(shiphead_order_id,0) > 0) 
         AND (SUM(noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned)) <= 0)) THEN 
           'altemphasis'
        WHEN ((COALESCE(cobmisc_cohead_id,0) > 0)       
         AND (SUM(noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned)) > 0)) THEN 
           'error' 
        WHEN (NOT shiphead_shipped) THEN 
          'emphasis' 
       END INTO _result
    FROM cohead
      JOIN coitem ON (cohead_id=coitem_cohead_id)
      JOIN shiphead ON ((shiphead_order_id=cohead_id)
                    AND (shiphead_order_type='SO'))
      JOIN shipitem ON (shiphead_id=shipitem_shiphead_id)
      LEFT OUTER JOIN (SELECT DISTINCT cobmisc_cohead_id FROM cobmisc) AS cobmisc ON (cobmisc_cohead_id=cohead_id) 
    WHERE (shiphead_id=_shipheadid)
    GROUP BY shiphead_id,shiphead_shipped,shiphead_order_id,cobmisc_cohead_id
    ORDER BY shiphead_id DESC;
  ELSE
    _result := '';
  END IF;
  
  RETURN _result;
  
END;

Function: public.concatagg(text)

Returns: text

Language: INTERNAL

aggregate_dummy

Function: public.concataggsfunc(text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  prevstate     ALIAS FOR $1;
  newval        ALIAS FOR $2;
BEGIN
  RETURN prevstate || newval;
END;

Function: public.consolidatelocations(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _r RECORD;

BEGIN

  UPDATE itemloc
  SET itemloc_consolflag = TRUE
  WHERE (itemloc_itemsite_id=pItemsiteid);

  FOR _r IN SELECT itemloc_location_id, SUM(itemloc_qty) AS qty
            FROM itemloc
            WHERE (itemloc_itemsite_id=pItemsiteid)
            GROUP BY itemloc_location_id LOOP
    INSERT INTO itemloc
    ( itemloc_itemsite_id, itemloc_location_id,
      itemloc_expiration, itemloc_qty, itemloc_consolflag )
    VALUES
    ( pItemsiteid, _r.itemloc_location_id,
      endOfTime(), _r.qty, FALSE );
  END LOOP;

  DELETE FROM itemloc
  WHERE ( (itemloc_itemsite_id=pItemsiteid)
   AND (itemloc_consolflag) );

  RETURN 1;

END;

Function: public.convertcustomertoprospect(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustId     ALIAS FOR $1;
  _c          RECORD;
BEGIN
  SELECT * INTO _c
  FROM custinfo
  WHERE (cust_id=pCustId);

  INSERT INTO prospect (
        prospect_id, prospect_active, prospect_number,
        prospect_name, prospect_cntct_id, prospect_taxzone_id,
        prospect_salesrep_id, prospect_warehous_id, prospect_comments
  ) VALUES (
       _c.cust_id, _c.cust_active, _c.cust_number,
       _c.cust_name, _c.cust_cntct_id, _c.cust_taxzone_id,
       CASE WHEN(_c.cust_salesrep_id > 0) THEN _c.cust_salesrep_id
            ELSE NULL
       END,
       CASE WHEN(_c.cust_preferred_warehous_id > 0) THEN _c.cust_preferred_warehous_id
            ELSE NULL
       END,
       _c.cust_comments);

  DELETE FROM custinfo WHERE (cust_id=pCustId);

  RETURN pCustId;
END;

Function: public.convertprospecttocustomer(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN convertProspectToCustomer($1, FALSE);
END;

Function: public.convertprospecttocustomer(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pProspectId ALIAS FOR $1;
  pdoquotes   ALIAS FOR $2;
  _p          RECORD;
  _q          RECORD;

BEGIN
  SELECT * INTO _p
  FROM prospect
  WHERE (prospect_id=pProspectId);

  IF (EXISTS(SELECT cust_id FROM custinfo WHERE cust_id=pProspectId)) THEN
    RAISE EXCEPTION '[xtuple: convertProspectToCustomer, -10]';
  END IF;

  INSERT INTO custinfo (
        cust_id, cust_active, cust_number,
        cust_name, cust_cntct_id, cust_taxzone_id,
        cust_comments, cust_creditstatus,
        cust_salesrep_id, cust_preferred_warehous_id,
        cust_terms_id,
        cust_custtype_id, cust_shipform_id,
        cust_shipvia, cust_balmethod,
        cust_ffshipto, cust_backorder,
        cust_partialship, cust_creditlmt,
        cust_creditrating, cust_commprcnt,
        cust_discntprcnt, cust_blanketpos,
        cust_shipchrg_id, cust_ffbillto,
        cust_usespos, cust_emaildelivery,
        cust_autoupdatestatus,cust_autoholdorders,
        cust_soemaildelivery) 
  SELECT
      _p.prospect_id, _p.prospect_active, _p.prospect_number,
      _p.prospect_name, _p.prospect_cntct_id, _p.prospect_taxzone_id,
      _p.prospect_comments, 'G',
      COALESCE(_p.prospect_salesrep_id, salesrep_id),
      COALESCE(_p.prospect_warehous_id, -1),
      FetchMetricValue('DefaultTerms'),
      FetchMetricValue('DefaultCustType'),
      FetchMetricValue('DefaultShipFormId'),
      COALESCE(FetchMetricValue('DefaultShipViaId'),-1),
      FetchMetricText('DefaultBalanceMethod'),
      FetchMetricBool('DefaultFreeFormShiptos'),
      FetchMetricBool('DefaultBackOrders'),
      FetchMetricBool('DefaultPartialShipments'),
      FetchMetricValue('SOCreditLimit'),
      FetchMetricText('SOCreditRate'),
      salesrep_commission,
      0, false, -1,false,false,false,false,
      false, false
  FROM salesrep WHERE (salesrep_id=FetchMetricValue('DefaultSalesRep'));

  DELETE FROM prospect WHERE (prospect_id=pprospectId);

  IF (pdoquotes) THEN
    BEGIN
      FOR _q IN SELECT quhead_number, convertQuote(quhead_id) AS err
                  FROM quhead
                 WHERE ((COALESCE(quhead_expire, endOfTime()) >= CURRENT_DATE)
                    AND (quhead_cust_id=pProspectId)) LOOP
        IF (_q.err < 0) THEN
          RAISE NOTICE 'Quote % for % didn''t convert to a Sales Order [xtuple: convertQuote, %]',
                       _q.quhead_number, _p.prospect_number, _q.err;
        END IF;
      END LOOP;
    EXCEPTION WHEN OTHERS THEN
      RAISE NOTICE 'Ignored errors convering quotes: % %', SQLSTATE, SQLERRM;
    END;
  END IF;

  RETURN pProspectId;
END;

Function: public.convertquote(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  _soheadid INTEGER;
  _soitemid INTEGER;
  _orderid INTEGER;
  _ordertype CHARACTER(1);
  _creditstatus	TEXT;
  _usespos BOOLEAN := false;
  _blanketpos BOOLEAN := true;
  _showConvertedQuote BOOLEAN := false;
  _prospectid	INTEGER;
  _r RECORD;
  _soNum TEXT;

BEGIN

-- Check to make sure the quote has not expired
  IF (SELECT COALESCE(quhead_expire, endOfTime()) < CURRENT_DATE
        FROM quhead
       WHERE(quhead_id=pQuheadid)) THEN
    RETURN -6;
  END IF;

--  Check to make sure that all of the quote items have a valid itemsite
  SELECT quitem_id INTO _r
    FROM quitem LEFT OUTER JOIN itemsite ON (quitem_itemsite_id=itemsite_id)
   WHERE ((itemsite_id IS NULL)
     AND  (quitem_quhead_id=pQuheadid));
  IF (FOUND) THEN
    INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number)
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'Q', quhead_id, quhead_warehous_id, quhead_number
    FROM evntnot, evnttype, quhead
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=quhead_warehous_id)
     AND (evnttype_name='CannotConvertQuote')
     AND (quhead_id=pQuheadid) );

    RETURN -1;
  END IF;

  SELECT cust_creditstatus, cust_usespos, cust_blanketpos
    INTO _creditstatus, _usespos, _blanketpos
  FROM quhead, custinfo
  WHERE ((quhead_cust_id=cust_id)
    AND  (quhead_id=pQuheadid));

  IF (NOT FOUND) THEN
    SELECT prospect_id INTO _prospectid
    FROM quhead, prospect
    WHERE ((quhead_cust_id=prospect_id)
      AND  (quhead_id=pQuheadid));
    IF (NOT FOUND) THEN
      RETURN -2;
    ELSE
      RETURN -3;
    END IF;
  ELSIF (_creditstatus = 'H' AND NOT checkPrivilege('CreateSOForHoldCustomer')) THEN
    RETURN -4;
  ELSIF (_creditstatus = 'W' AND NOT checkPrivilege('CreateSOForWarnCustomer')) THEN
    RETURN -5;
  END IF;

  IF ( (_usespos) AND (NOT _blanketpos) ) THEN
    PERFORM cohead_id
    FROM quhead JOIN cohead ON ( (cohead_cust_id=quhead_cust_id) AND
                                 (UPPER(cohead_custponumber)=UPPER(quhead_custponumber)) )
    WHERE (quhead_id=pQuheadid);
    IF (FOUND) THEN
      RAISE EXCEPTION 'Duplicate Customer PO';
    END IF;
  END IF;
  
  PERFORM quhead_number, cohead_id 
  FROM quhead, cohead 
  WHERE quhead_id = pQuheadid
  AND cohead_number = quhead_number;

  IF (FOUND) THEN
    SELECT fetchSoNumber() INTO _soNum;
  ELSE
    SELECT quhead_number INTO _soNum
    FROM quhead
    WHERE quhead_id = pQuheadid;
  END IF;

  SELECT NEXTVAL('cohead_cohead_id_seq') INTO _soheadid;
  INSERT INTO cohead
  ( cohead_id, cohead_number, cohead_cust_id,
    cohead_orderdate, cohead_packdate,
    cohead_custponumber, cohead_warehous_id,
    cohead_billtoname, cohead_billtoaddress1,
    cohead_billtoaddress2, cohead_billtoaddress3,
    cohead_billtocity, cohead_billtostate, cohead_billtozipcode,
    cohead_billtocountry,
    cohead_shipto_id, cohead_shiptoname, cohead_shiptoaddress1,
    cohead_shiptoaddress2, cohead_shiptoaddress3,
    cohead_shiptocity, cohead_shiptostate, cohead_shiptozipcode,
    cohead_shiptocountry,
    cohead_salesrep_id, cohead_commission,
    cohead_terms_id, cohead_origin, cohead_shipchrg_id, cohead_shipform_id,
    cohead_fob, cohead_shipvia,
    cohead_ordercomments, cohead_shipcomments,
    cohead_freight, cohead_misc, cohead_misc_accnt_id, cohead_misc_descrip,
    cohead_holdtype, cohead_wasquote, cohead_quote_number, cohead_prj_id,
    cohead_curr_id, cohead_taxzone_id, cohead_taxtype_id,
    cohead_shipto_cntct_id, cohead_shipto_cntct_honorific, cohead_shipto_cntct_first_name,
    cohead_shipto_cntct_middle, cohead_shipto_cntct_last_name, cohead_shipto_cntct_suffix,
    cohead_shipto_cntct_phone, cohead_shipto_cntct_title, cohead_shipto_cntct_fax, 
    cohead_shipto_cntct_email,
    cohead_billto_cntct_id, cohead_billto_cntct_honorific,
    cohead_billto_cntct_first_name, cohead_billto_cntct_middle, cohead_billto_cntct_last_name, 
    cohead_billto_cntct_suffix, cohead_billto_cntct_phone, cohead_billto_cntct_title, 
    cohead_billto_cntct_fax, cohead_billto_cntct_email, cohead_ophead_id,
    cohead_calcfreight, cohead_saletype_id, cohead_shipzone_id )
  SELECT _soheadid, _soNum, quhead_cust_id,
         CURRENT_DATE, quhead_packdate,
         quhead_custponumber, quhead_warehous_id,
         quhead_billtoname, quhead_billtoaddress1,
         quhead_billtoaddress2, quhead_billtoaddress3,
         quhead_billtocity, quhead_billtostate, quhead_billtozip,
         quhead_billtocountry,
         quhead_shipto_id, quhead_shiptoname, quhead_shiptoaddress1,
         quhead_shiptoaddress2, quhead_shiptoaddress3,
         quhead_shiptocity, quhead_shiptostate, quhead_shiptozipcode,
         quhead_shiptocountry,
         quhead_salesrep_id, quhead_commission,
         quhead_terms_id, quhead_origin, cust_shipchrg_id, cust_shipform_id,
         quhead_fob, quhead_shipvia,
         quhead_ordercomments, quhead_shipcomments,
         quhead_freight, quhead_misc, quhead_misc_accnt_id, quhead_misc_descrip,
         'N', TRUE, quhead_number, quhead_prj_id,
	 quhead_curr_id, quhead_taxzone_id, quhead_taxtype_id,
	 quhead_shipto_cntct_id, quhead_shipto_cntct_honorific,
	 quhead_shipto_cntct_first_name, quhead_shipto_cntct_middle, quhead_shipto_cntct_last_name,
	 quhead_shipto_cntct_suffix, quhead_shipto_cntct_phone, quhead_shipto_cntct_title,
	 quhead_shipto_cntct_fax, quhead_shipto_cntct_email, quhead_billto_cntct_id,
	 quhead_billto_cntct_honorific, quhead_billto_cntct_first_name, quhead_billto_cntct_middle,
	 quhead_billto_cntct_last_name, quhead_billto_cntct_suffix, quhead_billto_cntct_phone,
	 quhead_billto_cntct_title, quhead_billto_cntct_fax, quhead_billto_cntct_email, quhead_ophead_id,
         quhead_calcfreight, quhead_saletype_id, quhead_shipzone_id
  FROM quhead JOIN custinfo ON (cust_id=quhead_cust_id)
  WHERE (quhead_id=pQuheadid);

  UPDATE url SET url_source_id = _soheadid,
                 url_source = 'S'
  WHERE ((url_source='Q') AND (url_source_id = pQuheadid));

  UPDATE imageass SET imageass_source_id = _soheadid,
                      imageass_source = 'S'
  WHERE ((imageass_source='Q') AND (imageass_source_id = pQuheadid));

  UPDATE docass SET docass_source_id = _soheadid,
                    docass_source_type = 'S'
  WHERE ((docass_source_type='Q') AND (docass_source_id = pQuheadid));

  -- Copy Comments
  INSERT INTO comment
  ( comment_cmnttype_id, comment_source, comment_source_id, comment_date, comment_user, comment_text, comment_public )
  SELECT comment_cmnttype_id, 'S', _soheadid, comment_date, comment_user, ('Quote-' || comment_text), comment_public
  FROM comment
  WHERE ( (comment_source='Q')
    AND   (comment_source_id=pQuheadid) );

  FOR _r IN SELECT quitem.*,
                   quhead_number, quhead_prj_id,
                   itemsite_item_id, itemsite_leadtime,
                   itemsite_createsopo, itemsite_createsopr,
                   item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
            FROM quhead JOIN quitem ON (quitem_quhead_id=quhead_id)
                        JOIN itemsite ON (itemsite_id=quitem_itemsite_id)
                        JOIN item ON (item_id=itemsite_item_id)
                        LEFT OUTER JOIN itemsrc ON ( (itemsrc_item_id=item_id) AND
                                                     (itemsrc_default) )
            WHERE (quhead_id=pQuheadid)
            ORDER BY quitem_linenumber LOOP

    SELECT NEXTVAL('coitem_coitem_id_seq') INTO _soitemid;

    INSERT INTO coitem
    ( coitem_id, coitem_cohead_id, coitem_linenumber, coitem_itemsite_id,
      coitem_status, coitem_scheddate, coitem_promdate,
      coitem_price, coitem_custprice, 
      coitem_qtyord, coitem_qtyshipped, coitem_qtyreturned,
      coitem_qty_uom_id, coitem_qty_invuomratio,
      coitem_price_uom_id, coitem_price_invuomratio,
      coitem_unitcost, coitem_prcost,
      coitem_custpn, coitem_memo, coitem_taxtype_id, coitem_order_id )
    VALUES
    ( _soitemid, _soheadid, _r.quitem_linenumber, _r.quitem_itemsite_id,
      'O', _r.quitem_scheddate, _r.quitem_promdate,
      _r.quitem_price, _r.quitem_custprice,
      _r.quitem_qtyord, 0, 0,
      _r.quitem_qty_uom_id, _r.quitem_qty_invuomratio,
      _r.quitem_price_uom_id, _r.quitem_price_invuomratio,
      stdcost(_r.itemsite_item_id), _r.quitem_prcost,
      _r.quitem_custpn, _r.quitem_memo, _r.quitem_taxtype_id, -1 );

    IF (fetchMetricBool('enablextcommissionission')) THEN
      PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
                                        _r.itemsite_item_id, _r.quitem_price,
                                        _soitemid, 'SalesItem')
      FROM quhead
      WHERE (quhead_id=pQuheadid);
    END IF;

    INSERT INTO charass
          (charass_target_type, charass_target_id, charass_char_id, charass_value, charass_default, charass_price)
    SELECT 'SI', _soitemid, charass_char_id, charass_value, charass_default, charass_price
      FROM charass
     WHERE ((charass_target_type='QI')
       AND  (charass_target_id=_r.quitem_id));

    -- Copy Comments
    INSERT INTO comment
    ( comment_cmnttype_id, comment_source, comment_source_id, comment_date, comment_user, comment_text )
    SELECT comment_cmnttype_id, 'SI', _soitemid, comment_date, comment_user, ('Quote-' || comment_text)
    FROM comment
    WHERE ( (comment_source='QI')
      AND   (comment_source_id=_r.quitem_id) );

    _orderid := -1;
    _ordertype := '';
    IF (_r.quitem_createorder) THEN

      IF (_r.item_type IN ('M')) THEN
        SELECT createWo( CAST(_r.quhead_number AS INTEGER), supply.itemsite_id, 1, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
                         _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, 'S', _soitemid, _r.quhead_prj_id ) INTO _orderId
        FROM itemsite sold, itemsite supply
        WHERE ((sold.itemsite_item_id=supply.itemsite_item_id)
         AND (supply.itemsite_warehous_id=_r.quitem_order_warehous_id)
         AND (sold.itemsite_id=_r.quitem_itemsite_id) );
        _orderType := 'W';

        INSERT INTO charass
              (charass_target_type, charass_target_id, charass_char_id, charass_value)
        SELECT 'W', _orderId, charass_char_id, charass_value
          FROM charass
         WHERE ((charass_target_type='QI')
           AND  (charass_target_id=_r.quitem_id));

      ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopr) ) THEN
        SELECT createPr( CAST(_r.quhead_number AS INTEGER), _r.quitem_itemsite_id, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
                         _r.quitem_scheddate, '', 'S', _soitemid ) INTO _orderId;
        _orderType := 'R';
        UPDATE pr SET pr_prj_id=_r.quhead_prj_id WHERE pr_id=_orderId;
      ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopo) ) THEN
        IF (_r.quitem_prcost=0) THEN
          SELECT createPurchaseToSale(_soitemid, _r.itemsrcid, _r.quitem_dropship) INTO _orderId;
        ELSE
          SELECT createPurchaseToSale(_soitemid, _r.itemsrcid, _r.quitem_dropship, _r.quitem_prcost) INTO _orderId;
        END IF;
        _orderType := 'P';
      END IF;

      UPDATE coitem SET coitem_order_type=_ordertype, coitem_order_id=_orderid
      WHERE (coitem_id=_soitemid);

    END IF;

  END LOOP;

  SELECT metric_value INTO _showConvertedQuote
  FROM metric WHERE metric_name = 'ShowQuotesAfterSO';

  IF (_showConvertedQuote) THEN
    UPDATE quhead
    SET quhead_status= 'C'
    WHERE (quhead_id = pQuheadid);
  ELSE
  PERFORM deleteQuote(pQuheadid);
  END IF;

  RETURN _soheadid;

END;

Function: public.convertquotetoinvoice(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  _iheadid INTEGER;
  _iitemid INTEGER;
  _orderid INTEGER;
  _ordertype CHARACTER(1);
  _creditstatus	TEXT;
  _usespos BOOLEAN := false;
  _blanketpos BOOLEAN := true;
  _showConvertedQuote BOOLEAN := false;
  _prospectid	INTEGER;
  _r RECORD;
  _inNum TEXT;

BEGIN

-- Check to make sure the quote has not expired
  IF (SELECT COALESCE(quhead_expire, endOfTime()) < CURRENT_DATE
        FROM quhead
       WHERE(quhead_id=pQuheadid)) THEN
    RETURN -6;
  END IF;

--  Check to make sure that all of the quote items have a valid itemsite
  SELECT quitem_id INTO _r
    FROM quitem LEFT OUTER JOIN itemsite ON (quitem_itemsite_id=itemsite_id)
   WHERE ((itemsite_id IS NULL)
     AND  (quitem_quhead_id=pQuheadid));
  IF (FOUND) THEN
    INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number)
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'Q', quhead_id, quhead_warehous_id, quhead_number
    FROM evntnot, evnttype, quhead
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=quhead_warehous_id)
     AND (evnttype_name='CannotConvertQuote')
     AND (quhead_id=pQuheadid) );

    RETURN -1;
  END IF;

-- Get Credit Stat, Uses POs and Blanket POs

  SELECT cust_creditstatus, cust_usespos, cust_blanketpos
    INTO _creditstatus, _usespos, _blanketpos
  FROM quhead, custinfo
  WHERE ((quhead_cust_id=cust_id)
    AND  (quhead_id=pQuheadid));

-- Check to see if customer or prospect

  IF (NOT FOUND) THEN
    SELECT prospect_id INTO _prospectid
    FROM quhead, prospect
    WHERE ((quhead_cust_id=prospect_id)
      AND  (quhead_id=pQuheadid));
    IF (NOT FOUND) THEN
      RETURN -2;
    ELSE
      RETURN -3;
    END IF;
  ELSIF (_creditstatus = 'H' AND NOT hasPriv('CreateSOForHoldCustomer')) THEN
    RETURN -4;
  ELSIF (_creditstatus = 'W' AND NOT hasPriv('CreateSOForWarnCustomer')) THEN
    RETURN -5;
  END IF;

-- PO/blanket PO checks

  IF ( (_usespos) AND (NOT _blanketpos) ) THEN
    PERFORM invchead_id
    FROM quhead JOIN invchead ON ( (invchead_cust_id=quhead_cust_id) AND
                                 (UPPER(invchead_custponumber)=UPPER(quhead_custponumber)) )
    WHERE (quhead_id=pQuheadid);
    IF (FOUND) THEN
      RAISE EXCEPTION 'Duplicate Customer PO';
    END IF;
  END IF;

--Check to see if an invoice exists with the quote number
  
  PERFORM quhead_number, invchead_id 
  FROM quhead, invchead 
  WHERE quhead_id = pQuheadid
  AND invchead_invcnumber = quhead_number;

-- If it does then get a new Invoice number otherwise use the quote number as the invoice number

  IF (FOUND) THEN
    SELECT fetchinvcnumber() INTO _inNum;
  ELSE
    SELECT quhead_number INTO _inNum
    FROM quhead
    WHERE quhead_id = pQuheadid;
  END IF;

--Insert quote info into invoice tables

  SELECT NEXTVAL('invchead_invchead_id_seq') INTO _iheadid;
  INSERT INTO invchead
  ( invchead_ordernumber, invchead_shipdate, invchead_recurring,
    invchead_id, invchead_invcnumber, invchead_cust_id,
    invchead_orderdate, invchead_ponumber, 
    invchead_billto_name, invchead_billto_address1,
    invchead_billto_address2, invchead_billto_address3,
    invchead_billto_city, invchead_billto_state, invchead_billto_zipcode, invchead_billto_country,
    invchead_shipto_id, invchead_shipto_name, invchead_shipto_address1,
    invchead_shipto_address2, invchead_shipto_address3,
    invchead_shipto_city, invchead_shipto_state, invchead_shipto_zipcode, invchead_shipto_country, 
    invchead_salesrep_id, invchead_commission,
    invchead_terms_id, invchead_shipchrg_id, invchead_fob, invchead_shipvia,
    invchead_notes, invchead_freight, 
    invchead_misc_amount, invchead_misc_accnt_id, invchead_misc_descrip,
    invchead_prj_id, invchead_curr_id, invchead_taxzone_id,
    invchead_posted, invchead_printed, invchead_invcdate,
    invchead_saletype_id, invchead_shipzone_id
    --invchead_taxtype_id,
    --invchead_shipto_cntct_id, invchead_shipto_cntct_honorific, invchead_shipto_cntct_first_name,
    --invchead_shipto_cntct_middle, invchead_shipto_cntct_last_name, invchead_shipto_cntct_suffix,
    --invchead_shipto_cntct_phone, invchead_shipto_cntct_title, invchead_shipto_cntct_fax, 
    --invchead_shipto_cntct_email,
    --invchead_billto_cntct_id, invchead_billto_cntct_honorific,
    --invchead_billto_cntct_first_name, invchead_billto_cntct_middle, invchead_billto_cntct_last_name, 
    --invchead_billto_cntct_suffix, invchead_billto_cntct_phone, invchead_billto_cntct_title, 
    --invchead_billto_cntct_fax, invchead_billto_cntct_email, 
    --invchead_ophead_id,
    --invchead_calcfreight 
    )
  SELECT quhead_number, quhead_packdate, 'f',
         _iheadid, _inNum, quhead_cust_id,
         CURRENT_DATE, quhead_custponumber, 
         quhead_billtoname, quhead_billtoaddress1,
         quhead_billtoaddress2, quhead_billtoaddress3,
         quhead_billtocity, quhead_billtostate, quhead_billtozip, quhead_billtocountry,
         quhead_shipto_id, quhead_shiptoname, quhead_shiptoaddress1,
         quhead_shiptoaddress2, quhead_shiptoaddress3,
         quhead_shiptocity, quhead_shiptostate, quhead_shiptozipcode, quhead_shiptocountry,
         quhead_salesrep_id, quhead_commission,
         quhead_terms_id, cust_shipchrg_id, quhead_fob, quhead_shipvia,
         quhead_ordercomments,  quhead_freight,
         quhead_misc, quhead_misc_accnt_id, quhead_misc_descrip,
         quhead_prj_id, quhead_curr_id, quhead_taxzone_id,
         'f','f',current_date,
         quhead_saletype_id, quhead_shipzone_id
         --quhead_shipto_cntct_id, quhead_shipto_cntct_honorific,
	 --quhead_shipto_cntct_first_name, quhead_shipto_cntct_middle, quhead_shipto_cntct_last_name,
	 --quhead_shipto_cntct_suffix, quhead_shipto_cntct_phone, quhead_shipto_cntct_title,
	 --quhead_shipto_cntct_fax, quhead_shipto_cntct_email, quhead_billto_cntct_id,
	 --quhead_billto_cntct_honorific, quhead_billto_cntct_first_name, quhead_billto_cntct_middle,
	 --quhead_billto_cntct_last_name, quhead_billto_cntct_suffix, quhead_billto_cntct_phone,
	 --quhead_billto_cntct_title, quhead_billto_cntct_fax, quhead_billto_cntct_email, quhead_ophead_id,
         --quhead_calcfreight
  FROM quhead JOIN custinfo ON (cust_id=quhead_cust_id)
  WHERE (quhead_id=pQuheadid);

-- Attachments on Invoice not supported but leaving this in for future use:
/*
  UPDATE url SET url_source_id = _iheadid,
                 url_source = 'I'
  WHERE ((url_source='Q') AND (url_source_id = pQuheadid));

  UPDATE imageass SET imageass_source_id = _iheadid,
                      imageass_source = 'I'
  WHERE ((imageass_source='Q') AND (imageass_source_id = pQuheadid));

  UPDATE docass SET docass_source_id = _iheadid,
                    docass_source_type = 'I'
  WHERE ((docass_source_type='Q') AND (docass_source_id = pQuheadid));
*/


-- Comments not supported on Invoice but leaving this in for future use:

/*  
  INSERT INTO comment
  ( comment_cmnttype_id, comment_source, comment_source_id, comment_date, comment_user, comment_text, comment_public )
  SELECT comment_cmnttype_id, 'I', _iheadid, comment_date, comment_user, ('Quote-' || comment_text), comment_public
  FROM comment
  WHERE ( (comment_source='Q')
    AND   (comment_source_id=pQuheadid) );
*/

  FOR _r IN SELECT quitem.*,
                   quhead_number, quhead_prj_id,
                   itemsite_item_id, itemsite_leadtime,
                   itemsite_createsopo, itemsite_createsopr,
                   item_type, COALESCE(quitem_itemsrc_id, itemsrc_id, -1) AS itemsrcid
            FROM quhead JOIN quitem ON (quitem_quhead_id=quhead_id)
                        JOIN itemsite ON (itemsite_id=quitem_itemsite_id)
                        JOIN item ON (item_id=itemsite_item_id)
                        LEFT OUTER JOIN itemsrc ON ( (itemsrc_item_id=item_id) AND
                                                     (itemsrc_default) )
            WHERE (quhead_id=pQuheadid) LOOP

    SELECT NEXTVAL('invcitem_invcitem_id_seq') INTO _iitemid;

    INSERT INTO invcitem
    ( invcitem_id, invcitem_invchead_id, invcitem_linenumber, 
      invcitem_item_id,
      invcitem_warehous_id,
      --invcitem_status, 
      --invcitem_scheddate, invcitem_promdate,
      invcitem_price, invcitem_custprice, 
      invcitem_ordered, invcitem_billed,
      invcitem_qty_uom_id, invcitem_qty_invuomratio,
      invcitem_price_uom_id, invcitem_price_invuomratio,
      invcitem_custpn, invcitem_notes, invcitem_taxtype_id )
    VALUES
    ( _iitemid, _iheadid, _r.quitem_linenumber, 
      (SELECT itemsite_item_id FROM itemsite WHERE itemsite_id = _r.quitem_itemsite_id),
      (SELECT itemsite_warehous_id FROM itemsite WHERE itemsite_id = _r.quitem_itemsite_id),
      --'O', 
      --_r.quitem_scheddate, _r.quitem_promdate,
      _r.quitem_price, _r.quitem_custprice,
      _r.quitem_qtyord, _r.quitem_qtyord,
      _r.quitem_qty_uom_id, _r.quitem_qty_invuomratio,
      _r.quitem_price_uom_id, _r.quitem_price_invuomratio,
      _r.quitem_custpn, _r.quitem_memo, _r.quitem_taxtype_id );

    IF (fetchMetricBool('enablextcommissionission')) THEN
      PERFORM xtcommission.getSalesReps(quhead_cust_id, quhead_shipto_id,
                                        _r.itemsite_item_id, _r.quitem_price,
                                        _iitemid, 'InvoiceItem')
      FROM quhead
      WHERE (quhead_id=pQuheadid);
    END IF;

-- Chracteristics not supported on Invoice but leaving in for future use:

/*
    INSERT INTO charass
          (charass_target_type, charass_target_id, charass_char_id, charass_value, charass_default, charass_price)
    SELECT 'SI', _iitemid, charass_char_id, charass_value, charass_default, charass_price
      FROM charass
     WHERE ((charass_target_type='QI')
       AND  (charass_target_id=_r.quitem_id));
*/


-- Comments not supported but leaving in for future use

/*
    INSERT INTO comment
    ( comment_cmnttype_id, comment_source, comment_source_id, comment_date, comment_user, comment_text )
    SELECT comment_cmnttype_id, 'SI', _iitemid, comment_date, comment_user, ('Quote-' || comment_text)
    FROM comment
    WHERE ( (comment_source='QI')
      AND   (comment_source_id=_r.quitem_id) );
*/

    _orderid := -1;
    _ordertype := '';
    IF (_r.quitem_createorder) THEN

      IF (_r.item_type IN ('M')) THEN
        SELECT createWo( CAST(_r.quhead_number AS INTEGER), supply.itemsite_id, 1, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
                         _r.itemsite_leadtime, _r.quitem_scheddate, _r.quitem_memo, 'Q', _iitemid, _r.quhead_prj_id ) INTO _orderId
        FROM itemsite sold, itemsite supply
        WHERE ((sold.itemsite_item_id=supply.itemsite_item_id)
         AND (supply.itemsite_warehous_id=_r.quitem_order_warehous_id)
         AND (sold.itemsite_id=_r.quitem_itemsite_id) );
        _orderType := 'W';

        INSERT INTO charass
              (charass_target_type, charass_target_id, charass_char_id, charass_value)
        SELECT 'W', _orderId, charass_char_id, charass_value
          FROM charass
         WHERE ((charass_target_type='QI')
           AND  (charass_target_id=_r.quitem_id));

      ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopr) ) THEN
        SELECT createPr( CAST(_r.quhead_number AS INTEGER), _r.quitem_itemsite_id, (_r.quitem_qtyord * _r.quitem_qty_invuomratio),
                         _r.quitem_scheddate, '', 'S', _iitemid ) INTO _orderId;
        _orderType := 'R';
        UPDATE pr SET pr_prj_id=_r.quhead_prj_id WHERE pr_id=_orderId;
      ELSIF ( (_r.item_type IN ('P', 'O')) AND (_r.itemsite_createsopo) ) THEN
        IF (_r.quitem_prcost=0) THEN
-- For now quote to invoice/dropship will not be supported but with the creation of a createPurchaseToQuote() version of createPurchaseToSale()
-- it can be
--          SELECT createPurchaseToSale(_iitemid, _r.itemsrcid, _r.quitem_dropship) INTO _orderId;
            RAISE EXCEPTION 'Quote contains one or more dropship items that may not be converted from a Quote to an Invoice';
        ELSE
-- For now quote to invoice/dropship will not be supported but with the creation of a createPurchaseToQuote() version of createPurchaseToSale()
-- it can be
--          SELECT createPurchaseToSale(_iitemid, _r.itemsrcid, _r.quitem_dropship, _r.quitem_prcost) INTO _orderId;
            RAISE EXCEPTION 'Quote contains one or more dropship items that may not be converted from a Quote to an Invoice';
        END IF;
        _orderType := 'P';
      END IF;

--      UPDATE invcitem SET invcitem_order_type=_ordertype, invcitem_order_id=_orderid
--      WHERE (invcitem_id=_iitemid);

    END IF;

  END LOOP;

  SELECT metric_value INTO _showConvertedQuote
  FROM metric WHERE metric_name = 'ShowQuotesAfterSO';

  IF (_showConvertedQuote) THEN
    UPDATE quhead
    SET quhead_status= 'C'
    WHERE (quhead_id = pQuheadid);
  ELSE
     PERFORM deleteQuote(pQuheadid);
  END IF;

  RETURN _iheadid;

END;

Function: public.copybom(pcopyusedat integer, ptitemid integer, psitemid boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _bh RECORD;
  _bi RECORD;
  _bomheadid INTEGER;
  _bomitemid INTEGER;
  _bomworksetid INTEGER;
  _temp INTEGER;
  _schedatwooper BOOLEAN;
  _booitemseqid INTEGER;

BEGIN

--  Cache source bomhead
  SELECT * INTO _bh
  FROM bomhead
  WHERE ((bomhead_item_id=pSItemid)
    AND  (bomhead_rev_id=getActiveRevID('BOM', pSItemid)));

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

--  Make sure that source bomitems exist
  SELECT bomitem_id INTO _bomitemid
  FROM bomitem
  WHERE ((bomitem_parent_item_id=_bh.bomhead_item_id)
    AND  (bomitem_rev_id=_bh.bomhead_rev_id))
  LIMIT 1;

  IF (NOT FOUND) THEN
    RETURN -2;
  END IF;

--  Make sure that target bomitems do not exist
  SELECT bomitem_id INTO _bomitemid
  FROM bomitem
  WHERE ((bomitem_parent_item_id=pTItemid)
    AND  (bomitem_rev_id= -1))
  LIMIT 1;

  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Make sure that the parent is not used in the component at some level
  IF ( SELECT (item_type IN ('M', 'F'))
       FROM item
       WHERE (item_id=pSItemid) ) THEN
    SELECT indentedWhereUsed(pTItemid) INTO _bomworksetid;
    SELECT bomwork_id INTO _temp
    FROM bomwork
    WHERE ( (bomwork_set_id=_bomworksetid)
     AND (bomwork_item_id=pSItemid) )
    LIMIT 1;
    IF (FOUND) THEN
      PERFORM deleteBOMWorkset(_bomworksetid);
      RETURN -4;
    END IF;
    PERFORM deleteBOMWorkset(_bomworksetid);
  END IF;

--  Check for existing target bomhead
  SELECT bomhead_id INTO _bomheadid
  FROM bomhead
  WHERE ((bomhead_item_id=pTItemid)
    AND  (bomhead_rev_id= -1));

  IF (NOT FOUND) THEN
    INSERT INTO bomhead
    ( bomhead_item_id, bomhead_serial, bomhead_docnum,
      bomhead_batchsize, bomhead_requiredqtyper )
    VALUES
    ( pTItemid, _bh.bomhead_serial, _bh.bomhead_docnum,
      _bh.bomhead_batchsize, _bh.bomhead_requiredqtyper );
  END IF;

  FOR _bi IN SELECT bomitem.*
             FROM bomitem(pSItemid) 
             WHERE (bomitem_expires>CURRENT_DATE) LOOP

    SELECT NEXTVAL('bomitem_bomitem_id_seq') INTO _bomitemid;

    IF (pCopyUsedAt) THEN
      _schedatwooper := _bi.bomitem_schedatwooper;
      _booitemseqid := _bi.bomitem_booitem_seq_id;
    ELSE
      _schedatwooper := FALSE;
      _booitemseqid := -1;
    END IF;

    INSERT INTO bomitem
    ( bomitem_id, bomitem_parent_item_id, bomitem_seqnumber, bomitem_item_id,
      bomitem_uom_id, bomitem_qtyfxd, bomitem_qtyper, bomitem_scrap, bomitem_schedatwooper,
      bomitem_booitem_seq_id,
      bomitem_effective, bomitem_expires, bomitem_ecn,
      bomitem_createwo, bomitem_issuemethod, bomitem_moddate, bomitem_subtype,
      bomitem_notes, bomitem_ref )
    VALUES
    ( _bomitemid, pTItemid, _bi.bomitem_seqnumber, _bi.bomitem_item_id,
      _bi.bomitem_uom_id, _bi.bomitem_qtyfxd, _bi.bomitem_qtyper, _bi.bomitem_scrap, _schedatwooper,
      _booitemseqid,
      CURRENT_DATE, _bi.bomitem_expires, _bi.bomitem_ecn,
      _bi.bomitem_createwo, _bi.bomitem_issuemethod, CURRENT_DATE, _bi.bomitem_subtype,
      _bi.bomitem_notes, _bi.bomitem_ref );

    INSERT INTO bomitemsub
    ( bomitemsub_bomitem_id, bomitemsub_item_id,
      bomitemsub_uomratio, bomitemsub_rank )
    SELECT _bomitemid, bomitemsub_item_id,
           bomitemsub_uomratio, bomitemsub_rank
    FROM bomitemsub
    WHERE (bomitemsub_bomitem_id=_bi.bomitem_id);

  END LOOP;

  RETURN pTItemid;

END;

Function: public.copybom(ptitemid integer, psitemid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _result INTEGER;

BEGIN

  SELECT copyBOM (pSItemid, PTItemid, FALSE) into _result;

  RETURN _result;

END;

Function: public.copybudget(integer, text, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBudgheadid ALIAS FOR $1;
  pName ALIAS FOR $2;
  pDescrip ALIAS FOR $3;
  pInterval ALIAS FOR $4;
  _budgheadid INTEGER;
  _periodid INTEGER;
  _result INTEGER;

BEGIN
  SELECT 1 INTO _result
    FROM budgitem
   WHERE ((budgitem_budghead_id=pBudgheadid)
     AND  (nextPeriodByInterval(budgitem_period_id, pInterval)=-1))
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  SELECT nextval('budghead_budghead_id_seq') INTO _budgheadid;
  INSERT INTO budghead
        (budghead_id, budghead_name, budghead_descrip)
  VALUES(_budgheadid, pName, pDescrip);

  INSERT INTO budgitem (budgitem_budghead_id, budgitem_period_id,
                        budgitem_accnt_id, budgitem_amount)
  SELECT _budgheadid, nextPeriodByInterval(budgitem_period_id, pInterval),
         budgitem_accnt_id, budgitem_amount
    FROM budgitem
   WHERE (budgitem_budghead_id=pBudgheadid);

  RETURN _budgheadid;
END;

Function: public.copycmd(integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmdId	ALIAS FOR $1;
  pModule	ALIAS FOR $2;
  pTitle	ALIAS FOR $3;
  _cmdId	INTEGER;
BEGIN
    SELECT nextval('cmd_cmd_id_seq') INTO _cmdId;

    INSERT INTO cmd 
      SELECT _cmdId, pModule, pTitle, cmd_descrip, cmd_privname, cmd_executable
      FROM cmd
      WHERE (cmd_id=pCmdId);

    INSERT INTO cmdarg (cmdarg_cmd_id, cmdarg_order, cmdarg_arg)
      SELECT _cmdId, cmdarg_order, cmdarg_arg
      FROM cmdarg
      WHERE (cmdarg_cmd_id=pCmdId);

    RETURN 1;
END;

Function: public.copycontract(pexpires integer, peffective text, pnumber date, pcontrctid date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _contrctid INTEGER;
  _itemsrcid INTEGER;
  _r RECORD;

BEGIN

  INSERT INTO contrct
  ( contrct_number,
    contrct_vend_id,
    contrct_descrip,
    contrct_effective,
    contrct_expires,
    contrct_note )
  SELECT
    pNumber,
    contrct_vend_id,
    contrct_descrip,
    pEffective,
    pExpires,
    contrct_note
  FROM contrct
  WHERE (contrct_id=pContrctid)
  RETURNING contrct_id INTO _contrctid;

  FOR _r IN
  SELECT * FROM itemsrc WHERE (itemsrc_contrct_id=pContrctid)
  LOOP
  INSERT INTO itemsrc
    ( itemsrc_item_id,
      itemsrc_vend_id,
      itemsrc_vend_item_number,
      itemsrc_vend_item_descrip,
      itemsrc_comments,
      itemsrc_vend_uom,
      itemsrc_invvendoruomratio,
      itemsrc_minordqty,
      itemsrc_multordqty,
      itemsrc_leadtime,
      itemsrc_ranking,
      itemsrc_active,
      itemsrc_manuf_name,
      itemsrc_manuf_item_number,
      itemsrc_manuf_item_descrip,
      itemsrc_default,
      itemsrc_upccode,
      itemsrc_effective,
      itemsrc_expires,
      itemsrc_contrct_id )
    VALUES
    ( _r.itemsrc_item_id,
      _r.itemsrc_vend_id,
      _r.itemsrc_vend_item_number,
      _r.itemsrc_vend_item_descrip,
      _r.itemsrc_comments,
      _r.itemsrc_vend_uom,
      _r.itemsrc_invvendoruomratio,
      _r.itemsrc_minordqty,
      _r.itemsrc_multordqty,
      _r.itemsrc_leadtime,
      _r.itemsrc_ranking,
      _r.itemsrc_active,
      _r.itemsrc_manuf_name,
      _r.itemsrc_manuf_item_number,
      _r.itemsrc_manuf_item_descrip,
      _r.itemsrc_default,
      _r.itemsrc_upccode,
      pEffective,
      pExpires,
      _contrctid )
    RETURNING itemsrc_id INTO _itemsrcid;

  INSERT INTO itemsrcp
    ( itemsrcp_itemsrc_id,
      itemsrcp_qtybreak,
      itemsrcp_price,
      itemsrcp_updated,
      itemsrcp_curr_id,
      itemsrcp_dropship,
      itemsrcp_warehous_id,
      itemsrcp_type,
      itemsrcp_discntprcnt,
      itemsrcp_fixedamtdiscount )
    SELECT
      _itemsrcid,
      itemsrcp_qtybreak,
      itemsrcp_price,
      CURRENT_DATE,
      itemsrcp_curr_id,
      itemsrcp_dropship,
      itemsrcp_warehous_id,
      itemsrcp_type,
      itemsrcp_discntprcnt,
      itemsrcp_fixedamtdiscount
    FROM itemsrcp
    WHERE (itemsrcp_itemsrc_id=_r.itemsrc_id);

  END LOOP;

  RETURN _contrctid;

END;

Function: public.copyfinancialgroup(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceGroup ALIAS FOR $1;
  pFlheadid ALIAS FOR $2;
  pParentFlgrpid ALIAS FOR $3;

  _flgrpid INTEGER;

BEGIN

  SELECT nextval('flgrp_flgrp_id_seq') INTO _flgrpid;

-- Copy the group item
  INSERT INTO flgrp
         (flgrp_id, flgrp_flhead_id, flgrp_flgrp_id,
          flgrp_order, flgrp_name, flgrp_descrip,
          flgrp_subtotal, flgrp_summarize, flgrp_subtract,
          flgrp_showstart, flgrp_showend,
          flgrp_showdelta, flgrp_showbudget, flgrp_showdiff, flgrp_showcustom,
          flgrp_showstartprcnt, flgrp_showendprcnt,
          flgrp_showdeltaprcnt, flgrp_showbudgetprcnt, flgrp_showdiffprcnt, flgrp_showcustomprcnt,
          flgrp_usealtsubtotal, flgrp_altsubtotal,flgrp_prcnt_flgrp_id)
  SELECT _flgrpid, pFlheadid, pParentFlgrpid,
         flgrp_order, flgrp_name, flgrp_descrip,
         flgrp_subtotal, flgrp_summarize, flgrp_subtract,
         flgrp_showstart, flgrp_showend,
         flgrp_showdelta, flgrp_showbudget, flgrp_showdiff, flgrp_showcustom,
         flgrp_showstartprcnt, flgrp_showendprcnt,
         flgrp_showdeltaprcnt, flgrp_showbudgetprcnt, flgrp_showdiffprcnt, flgrp_showcustomprcnt,
         flgrp_usealtsubtotal, flgrp_altsubtotal,flgrp_prcnt_flgrp_id
    FROM flgrp
   WHERE (flgrp_id=pSourceGroup);

-- Store temporary cross ref info
   
   EXECUTE ' INSERT INTO tmp_flgrpxref' || getEffectiveXtUser() || ' (flgrpxref_oldid,flgrpxref_newid) VALUES (' || pSourceGroup || ',' || _flgrpid || ');';

-- Copy any children flitems
  INSERT INTO flitem
         (flitem_flhead_id, flitem_flgrp_id,
          flitem_order, flitem_accnt_id, flitem_showstart,
          flitem_showend, flitem_showdelta, flitem_showbudget, flitem_showdiff, flitem_showcustom,
          flitem_subtract, flitem_showstartprcnt,
          flitem_showendprcnt, flitem_showdeltaprcnt,
          flitem_showbudgetprcnt, flitem_showdiffprcnt, flitem_showcustomprcnt,
          flitem_custom_source, flitem_company, flitem_profit, flitem_number,
          flitem_sub, flitem_type, flitem_subaccnttype_code, flitem_prcnt_flgrp_id)
  SELECT pFlheadid, _flgrpid,
         flitem_order, flitem_accnt_id, flitem_showstart,
         flitem_showend, flitem_showdelta, flitem_showbudget, flitem_showdiff, flitem_showcustom,
         flitem_subtract, flitem_showstartprcnt,
         flitem_showendprcnt, flitem_showdeltaprcnt,
         flitem_showbudgetprcnt, flitem_showdiffprcnt, flitem_showcustomprcnt,
         flitem_custom_source, flitem_company, flitem_profit, flitem_number,
          flitem_sub, flitem_type, flitem_subaccnttype_code, flitem_prcnt_flgrp_id
    FROM flitem
   WHERE (flitem_flgrp_id=pSourceGroup);

-- Copy any children flspecs
  INSERT INTO flspec
         (flspec_flhead_id, flspec_flgrp_id,
          flspec_order, flspec_name, flspec_type, flspec_showstart,
          flspec_showend, flspec_showdelta, flspec_showbudget, flspec_showdiff, flspec_showcustom,
          flspec_subtract, flspec_showstartprcnt,
          flspec_showendprcnt, flspec_showdeltaprcnt,
          flspec_showbudgetprcnt, flspec_showdiffprcnt, flspec_showcustomprcnt,
          flspec_custom_source, flspec_prcnt_flgrp_id)
  SELECT pFlheadid, _flgrpid,
         flspec_order, flspec_name, flspec_type, flspec_showstart,
         flspec_showend, flspec_showdelta, flspec_showbudget, flspec_showdiff, flspec_showcustom,
         flspec_subtract, flspec_showstartprcnt,
         flspec_showendprcnt, flspec_showdeltaprcnt,
         flspec_showbudgetprcnt, flspec_showdiffprcnt, flspec_showcustomprcnt,
         flspec_custom_source, flspec_prcnt_flgrp_id
    FROM flspec
   WHERE (flspec_flgrp_id=pSourceGroup);

-- Copy the groups
  PERFORM copyFinancialGroup(flgrp_id, pFlheadid, _flgrpid)
     FROM flgrp
    WHERE (flgrp_flgrp_id=pSourceGroup);

  RETURN _flgrpid;
END;

Function: public.copyfinanciallayout(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceFlheadid ALIAS FOR $1;
  pDestName ALIAS FOR $2;

  _flheadid INTEGER;
  _tblName TEXT;

BEGIN

-- Check for the flhead to be copy that it exists
  PERFORM flhead_id
     FROM flhead
    WHERE (flhead_id=pSourceFlheadid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

-- Check that the name is valid
  IF (pDestName IS NULL OR pDestName = '') THEN
    RETURN -2;
  END IF;

-- Check for the name to copy to does not exist
  PERFORM flhead_id
     FROM flhead
    WHERE (flhead_name=pDestName);
  IF (FOUND) THEN
    RETURN -3;
  END IF;

-- Copy the flhead record
  SELECT nextval('flhead_flhead_id_seq') INTO _flheadid;
  INSERT INTO flhead
         (flhead_id, flhead_name, flhead_descrip,
          flhead_showtotal, flhead_showstart,
          flhead_showend, flhead_showdelta, flhead_showbudget,
          flhead_showdiff, flhead_showcustom,
          flhead_custom_label,
          flhead_usealttotal, flhead_alttotal,
          flhead_usealtbegin, flhead_altbegin,
          flhead_usealtend, flhead_altend,
          flhead_usealtdebits, flhead_altdebits,
          flhead_usealtcredits, flhead_altcredits,
          flhead_usealtbudget, flhead_altbudget,
          flhead_usealtdiff, flhead_altdiff,
          flhead_type, flhead_active, flhead_sys
)
  SELECT _flheadid, pDestName, flhead_descrip,
         flhead_showtotal, flhead_showstart,
         flhead_showend, flhead_showdelta, flhead_showbudget,
         flhead_showdiff, flhead_showcustom,
         flhead_custom_label,
         flhead_usealttotal, flhead_alttotal,
         flhead_usealtbegin, flhead_altbegin,
         flhead_usealtend, flhead_altend,
         flhead_usealtdebits, flhead_altdebits,
         flhead_usealtcredits, flhead_altcredits,
         flhead_usealtbudget, flhead_altbudget,
         flhead_usealtdiff, flhead_altdiff,
         flhead_type, flhead_active, false
    FROM flhead
   WHERE (flhead_id=pSourceFlheadid);

-- Create temporary table so old and new group ids can be stored
 SELECT relname FROM pg_class INTO _tblName
 WHERE relname = 'tmp_flgrpxref';
 IF (_tblName IS NULL) THEN
  EXECUTE 'CREATE TEMPORARY TABLE tmp_flgrpxref' || getEffectiveXtUser() || ' 
  (
	flgrpxref_oldid int4,
	flgrpxref_newid int4
  ) ON COMMIT DROP;';
  END IF;

-- Copy the top level groups
  PERFORM copyFinancialGroup(flgrp_id, _flheadid, -1)
     FROM flgrp
    WHERE ((flgrp_flhead_id=pSourceFlheadid)
      AND  (flgrp_flgrp_id=-1));

-- Update Group Percent settings
  EXECUTE 'UPDATE flgrp
  SET flgrp_prcnt_flgrp_id=flgrpxref_newid
  FROM tmp_flgrpxref' || getEffectiveXtUser() || ' 
  WHERE ((flgrp_flhead_id=' || _flheadid || ')
  AND (flgrp_prcnt_flgrp_id=flgrpxref_oldid));';

  EXECUTE 'UPDATE flitem
  SET flitem_prcnt_flgrp_id=flgrpxref_newid
  FROM tmp_flgrpxref' || getEffectiveXtUser() || ' 
  WHERE ((flitem_flhead_id=' || _flheadid || ')
  AND (flitem_prcnt_flgrp_id=flgrpxref_oldid));';

  EXECUTE 'UPDATE flspec
  SET flspec_prcnt_flgrp_id=flgrpxref_newid
  FROM tmp_flgrpxref' || getEffectiveXtUser() || ' 
  WHERE ((flspec_flhead_id=' || _flheadid || ')
  AND (flspec_prcnt_flgrp_id=flgrpxref_oldid));';

-- Copy Column Layounts
  INSERT INTO flcol
        (flcol_flhead_id,
        flcol_name,
        flcol_descrip,
        flcol_report_id,
        flcol_month,
        flcol_quarter,
        flcol_year,
        flcol_showdb,
        flcol_prcnt,
        flcol_priortype,
        flcol_priormonth,
        flcol_priorquarter,
        flcol_prioryear,
        flcol_priorprcnt,
        flcol_priordiff,
        flcol_priordiffprcnt,
        flcol_budget,
        flcol_budgetprcnt,
        flcol_budgetdiff,
        flcol_budgetdiffprcnt
)
SELECT
        _flheadid,flcol_name,flcol_descrip,
        flcol_report_id,flcol_month,flcol_quarter,
        flcol_year,flcol_showdb,flcol_prcnt,
        flcol_priortype,flcol_priormonth,flcol_priorquarter,
        flcol_prioryear,flcol_priorprcnt,flcol_priordiff,
        flcol_priordiffprcnt,flcol_budget,flcol_budgetprcnt,
        flcol_budgetdiff,flcol_budgetdiffprcnt
FROM flcol
WHERE (flcol_flhead_id=pSourceFlheadid);

  RETURN _flheadid;
END;

Function: public.copyglseries(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  _sequence INTEGER := fetchGLSequence();
  _journal INTEGER;	

BEGIN

  SELECT gltrans_journalnumber INTO _journal
  FROM gltrans
  WHERE ( gltrans_sequence=pSequence )
  LIMIT 1;

  IF (FOUND) THEN
    INSERT INTO glseries
    ( glseries_sequence, glseries_source, glseries_doctype, glseries_docnumber,
      glseries_notes, glseries_accnt_id, glseries_amount, glseries_distdate )
    SELECT _sequence, gltrans_source, gltrans_doctype, gltrans_docnumber,
           gltrans_notes, gltrans_accnt_id,
           gltrans_amount, gltrans_date
    FROM gltrans
    WHERE ( gltrans_sequence=pSequence );
  ELSE
    RAISE EXCEPTION 'g/l transaction sequence not found';
  END IF;

  RETURN _sequence;
END;

Function: public.copyincdt(integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pparentid   ALIAS FOR $1;
  ptimestamp  TIMESTAMP WITH TIME ZONE := COALESCE($2, CURRENT_TIMESTAMP);

  _alarmid    INTEGER;
  _incdtid    INTEGER;
  _todoitemid INTEGER;

BEGIN
  INSERT INTO incdt(incdt_number,          incdt_crmacct_id,
                    incdt_cntct_id,        incdt_summary,
                    incdt_descrip,         incdt_item_id,
                    incdt_timestamp,       incdt_incdtcat_id,
                    incdt_incdtseverity_id,incdt_incdtpriority_id,
                    incdt_owner_username,  incdt_recurring_incdt_id
           ) SELECT fetchIncidentNumber(), incdt_crmacct_id,
                    incdt_cntct_id,        incdt_summary,
                    incdt_descrip,         incdt_item_id,
                    ptimestamp,            incdt_incdtcat_id,
                    incdt_incdtseverity_id,incdt_incdtpriority_id,
                    incdt_owner_username,  incdt_recurring_incdt_id
               FROM incdt
              WHERE (incdt_id=pparentid)
  RETURNING incdt_id INTO _incdtid;

  IF (_incdtid IS NULL) THEN
    RETURN -10;
  END IF;

  SELECT MIN(copyTodoitem(todoitem_id, CAST(ptimestamp AS DATE), _incdtid))
            INTO _todoitemid
    FROM todoitem
   WHERE (todoitem_incdt_id=pparentid);

  IF (_todoitemid < 0) THEN
    RETURN _todoitemid;
  END IF;

  SELECT saveAlarm(NULL, NULL, CAST(ptimestamp AS DATE),
                   CAST(alarm_time - DATE_TRUNC('day',alarm_time) AS TIME),
                   alarm_time_offset,
                   alarm_time_qualifier,
                   alarm_event_recipient  IS NOT NULL, alarm_event_recipient,
                   alarm_email_recipient  IS NOT NULL, alarm_email_recipient,
                   alarm_sysmsg_recipient IS NOT NULL, alarm_sysmsg_recipient,
                   'INCDT', _incdtid, 'CHANGEONE')
    INTO _alarmid
    FROM alarm
   WHERE ((alarm_source='INCDT')
      AND (alarm_source_id=pparentid));

   IF (_alarmid < 0) THEN
     RETURN _alarmid;
   END IF;

   INSERT INTO docass (docass_source_id, docass_source_type,
                       docass_target_id, docass_target_type, docass_purpose
              ) SELECT _incdtid,       'INCDT',
                       docass_target_id, docass_target_type, docass_purpose
                  FROM docass
                 WHERE ((docass_source_id=pparentid)
                    AND (docass_source_type='INCDT'));

  RETURN _incdtid;
END;

Function: public.copyinvoice(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  _invcheadid INTEGER;
  _invcnumber TEXT;
  _invcdate DATE := COALESCE($2, CURRENT_DATE);
  _i RECORD;
  _l RECORD;
  _invcitemid INTEGER;

BEGIN
  SELECT *
    INTO _i
    FROM invchead
   WHERE(invchead_id=pInvcheadid);
  IF(NOT FOUND) THEN
    RETURN -1;
  END IF;

  _invcnumber := fetchInvcNumber();
  _invcheadid := nextval('invchead_invchead_id_seq');

  INSERT INTO invchead
        (invchead_id,
         invchead_cust_id, invchead_shipto_id,
         invchead_ordernumber, invchead_orderdate,
         invchead_posted, invchead_printed,
         invchead_invcnumber, invchead_invcdate, invchead_shipdate,
         invchead_ponumber, invchead_shipvia,
         invchead_fob, invchead_billto_name,
         invchead_billto_address1, invchead_billto_address2,
         invchead_billto_address3, invchead_billto_city,
         invchead_billto_state, invchead_billto_zipcode,
         invchead_billto_phone, invchead_shipto_name,
         invchead_shipto_address1, invchead_shipto_address2,
         invchead_shipto_address3, invchead_shipto_city,
         invchead_shipto_state, invchead_shipto_zipcode,
         invchead_shipto_phone, invchead_salesrep_id,
         invchead_commission,
         invchead_terms_id, invchead_freight,
         invchead_misc_amount,
         invchead_misc_descrip, invchead_misc_accnt_id,
         invchead_payment, invchead_paymentref,
         invchead_notes,
         invchead_billto_country, invchead_shipto_country,
         invchead_prj_id, invchead_curr_id,
         invchead_taxzone_id,
         invchead_recurring_invchead_id,
         invchead_saletype_id, invchead_shipzone_id)
  VALUES(_invcheadid,
         _i.invchead_cust_id, _i.invchead_shipto_id,
         _i.invchead_ordernumber, _i.invchead_orderdate,
         false, false,
         _invcnumber, _invcdate, _i.invchead_shipdate,
         _i.invchead_ponumber, _i.invchead_shipvia,
         _i.invchead_fob, _i.invchead_billto_name,
         _i.invchead_billto_address1, _i.invchead_billto_address2,
         _i.invchead_billto_address3, _i.invchead_billto_city,
         _i.invchead_billto_state, _i.invchead_billto_zipcode,
         _i.invchead_billto_phone, _i.invchead_shipto_name,
         _i.invchead_shipto_address1, _i.invchead_shipto_address2,
         _i.invchead_shipto_address3, _i.invchead_shipto_city,
         _i.invchead_shipto_state, _i.invchead_shipto_zipcode,
         _i.invchead_shipto_phone, _i.invchead_salesrep_id,
         _i.invchead_commission,
         _i.invchead_terms_id, _i.invchead_freight,
         _i.invchead_misc_amount,
         _i.invchead_misc_descrip, _i.invchead_misc_accnt_id,
         _i.invchead_payment, _i.invchead_paymentref,
         _i.invchead_notes,
         _i.invchead_billto_country, _i.invchead_shipto_country,
         _i.invchead_prj_id, _i.invchead_curr_id,
         _i.invchead_taxzone_id,
         _i.invchead_recurring_invchead_id,
         _i.invchead_saletype_id, _i.invchead_shipzone_id);

  FOR _l IN SELECT *
            FROM invcitem
            WHERE (invcitem_invchead_id=pInvcheadid) LOOP
    SELECT NEXTVAL('invcitem_invcitem_id_seq') INTO _invcitemid;

    INSERT INTO invcitem
        (invcitem_id, invcitem_invchead_id,
         invcitem_linenumber, invcitem_item_id,
         invcitem_warehous_id, invcitem_custpn,
         invcitem_number, invcitem_descrip,
         invcitem_ordered, invcitem_billed,
         invcitem_custprice, invcitem_price,
         invcitem_notes, invcitem_salescat_id,
         invcitem_taxtype_id,
         invcitem_qty_uom_id, invcitem_qty_invuomratio,
         invcitem_price_uom_id, invcitem_price_invuomratio,
         invcitem_coitem_id)
    VALUES
        (_invcitemid, _invcheadid,
         _l.invcitem_linenumber, _l.invcitem_item_id,
         _l.invcitem_warehous_id, _l.invcitem_custpn,
         _l.invcitem_number, _l.invcitem_descrip,
         _l.invcitem_ordered, _l.invcitem_billed,
         _l.invcitem_custprice, _l.invcitem_price,
         _l.invcitem_notes, _l.invcitem_salescat_id,
         _l.invcitem_taxtype_id,
         _l.invcitem_qty_uom_id, _l.invcitem_qty_invuomratio,
         _l.invcitem_price_uom_id, _l.invcitem_price_invuomratio,
         _l.invcitem_coitem_id);

  END LOOP;

  RETURN _invcheadid;
END;

Function: public.copyitem(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSItemid ALIAS FOR $1;
  pTItemNumber ALIAS FOR $2;
  _itemid INTEGER;
  _r RECORD;
  _id INTEGER;

BEGIN

  SELECT NEXTVAL('item_item_id_seq') INTO _itemid;
  INSERT INTO item
  ( item_id, item_number, item_descrip1, item_descrip2,
    item_classcode_id, item_type,
    item_active, item_picklist, item_sold, item_fractional,
    item_maxcost, item_prodweight, item_packweight,
    item_prodcat_id,item_exclusive, item_listprice, item_listcost,
    item_config, item_comments, item_extdescrip,
    item_upccode, item_inv_uom_id, item_price_uom_id )
  SELECT _itemid, pTItemNumber, item_descrip1, item_descrip2,
         item_classcode_id, item_type,
         item_active, item_picklist, item_sold, item_fractional,
         item_maxcost, item_prodweight, item_packweight,
         item_prodcat_id, item_exclusive, item_listprice, item_listcost,
         item_config, item_comments, item_extdescrip,
         item_upccode, item_inv_uom_id, item_price_uom_id
  FROM item
  WHERE (item_id=pSItemid);

  INSERT INTO imageass
  (imageass_source_id, imageass_source, imageass_image_id, imageass_purpose)
  SELECT _itemid, 'I', imageass_image_id, imageass_purpose
  FROM imageass
  WHERE ((imageass_source_id=pSItemid)
  AND (imageass_source='I'));
  
  INSERT INTO url
  (url_source_id, url_source, url_title, url_url)
  SELECT _itemid, 'I', url_title, url_url
  FROM url
  WHERE ((url_source_id=pSItemid)
  AND (url_source='I'));

  INSERT INTO itemtax
        (itemtax_item_id, itemtax_taxzone_id, itemtax_taxtype_id)
  SELECT _itemid, itemtax_taxzone_id, itemtax_taxtype_id
    FROM itemtax
   WHERE(itemtax_item_id=pSItemid);

  INSERT INTO charass
  ( charass_target_type, charass_target_id,
    charass_char_id, charass_value )
  SELECT 'I', _itemid, charass_char_id, charass_value
  FROM charass
  WHERE ( (charass_target_type='I')
   AND (charass_target_id=pSItemid) );

  FOR _r IN SELECT itemuomconv_id,
                   itemuomconv_from_uom_id,
                   itemuomconv_from_value,
                   itemuomconv_to_uom_id,
                   itemuomconv_to_value,
                   itemuomconv_fractional
              FROM itemuomconv
             WHERE(itemuomconv_item_id=pSItemid) LOOP
    SELECT nextval('itemuomconv_itemuomconv_id_seq') INTO _id;
    INSERT INTO itemuomconv
          (itemuomconv_id, itemuomconv_item_id,
           itemuomconv_from_uom_id, itemuomconv_from_value,
           itemuomconv_to_uom_id, itemuomconv_to_value,
           itemuomconv_fractional)
    VALUES(_id, _itemid,
           _r.itemuomconv_from_uom_id, _r.itemuomconv_from_value,
           _r.itemuomconv_to_uom_id, _r.itemuomconv_to_value,
           _r.itemuomconv_fractional);

    INSERT INTO itemuom
          (itemuom_itemuomconv_id, itemuom_uomtype_id)
    SELECT _id, itemuom_uomtype_id
      FROM itemuom
     WHERE(itemuom_itemuomconv_id=_r.itemuomconv_id);
  END LOOP;

  RETURN _itemid;

END;

Function: public.copyitem(integer, text, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSItemid      ALIAS FOR $1;
  pTItemNumber  ALIAS FOR $2;
  pCopyBOM      ALIAS FOR $3;
  pCopyCosts    ALIAS FOR $4;

  _itemid       INTEGER;
BEGIN

  _itemid := copyItem(pSItemid, pTItemNumber);

  IF (pCopyBOM) THEN
    PERFORM copyBOM(pSItemid, _itemid, FALSE);
  END IF;

  IF (pCopyCosts) THEN
    INSERT INTO itemcost
    ( itemcost_item_id, itemcost_costelem_id, itemcost_lowlevel,
      itemcost_stdcost, itemcost_posted,
      itemcost_actcost, itemcost_curr_id, itemcost_updated )
    SELECT _itemid, itemcost_costelem_id, itemcost_lowlevel,
      itemcost_stdcost, CURRENT_DATE,
      itemcost_actcost, itemcost_curr_id, CURRENT_DATE
    FROM itemcost
    WHERE (itemcost_item_id=pSItemid);
  END IF;

  RETURN _itemid;

END;

Function: public.copyitem(integer, text, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSItemid ALIAS FOR $1;
  pTItemNumber ALIAS FOR $2;
  pCopyBOM ALIAS FOR $3;
  pCopyBOO ALIAS FOR $4;        -- deprecated - xtmfg-specific
  pCopyCosts ALIAS FOR $5;
BEGIN
  RAISE NOTICE 'copyItem(INTEGER, TEXT, BOOLEAN, BOOLEAN, BOOLEAN) has been deprecated.  Use copyItem(INTEGER, TEXT) or copyItem(INTEGER, TEXT, BOOLEAN, BOOLEAN) or a package-specific version instead.';
  RETURN copyItem(pSItemid, pTItemNumber, pCopyBOM, pCopyCosts);
END;

Function: public.copyitem(integer, text, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSItemid ALIAS FOR $1;
  pTItemNumber ALIAS FOR $2;
  pCopyBOM ALIAS FOR $3;
  pCopyBOO ALIAS FOR $4;        -- deprecated - xtmfg-specific
  pCopyCosts ALIAS FOR $5;
  pCopyUsedAt ALIAS FOR $6;     -- deprecated - xtmfg-specific
BEGIN
  RETURN copyItem(pSItemid, pTItemNumber, pCopyBOM, pCopyCosts);
END;

Function: public.copyitemsite(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pitemsiteid	ALIAS FOR $1;
  pdestwhsid	ALIAS FOR $2;
  _destwhs	whsinfo%ROWTYPE;
  _new		itemsite%ROWTYPE;

BEGIN
  -- make a copy of the old itemsite
  SELECT * INTO _new
  FROM itemsite
  WHERE (itemsite_id=pitemsiteid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  -- if there is no dest warehouse then perhaps the user is manually copying it
  IF (pdestwhsid IS NOT NULL) THEN
    SELECT * INTO _destwhs
    FROM whsinfo
    WHERE (warehous_id=pdestwhsid);
    IF (NOT FOUND) THEN
      RETURN -2;
    END IF;
  END IF;

  IF (NOT checkPrivilege('MaintainItemSites')) THEN
    RETURN -3;
  END IF;

  SELECT itemsite_id INTO _new.itemsite_id
  FROM itemsite
  WHERE ((itemsite_item_id=_new.itemsite_item_id)
    AND  (itemsite_warehous_id=pdestwhsid OR
	  (itemsite_warehous_id IS NULL AND pdestwhsid IS NULL)));
  IF (FOUND) THEN
    RETURN _new.itemsite_id;
  END IF;

  -- now override the things we know have to change
  _new.itemsite_id		:= NEXTVAL('itemsite_itemsite_id_seq');
  _new.itemsite_warehous_id	:= pdestwhsid;
  _new.itemsite_qtyonhand	:= 0;
  _new.itemsite_value           := 0;
  _new.itemsite_datelastcount	:= NULL;
  _new.itemsite_datelastused	:= NULL;
  _new.itemsite_nnqoh		:= 0;
  _new.itemsite_location_id    := -1;

  IF (_destwhs.warehous_transit) THEN
    _new.itemsite_reorderlevel	:= 0;
    _new.itemsite_ordertoqty	:= 0;
    _new.itemsite_soldranking	:= NULL;
    _new.itemsite_posupply	:= FALSE;
    _new.itemsite_wosupply	:= FALSE;
    _new.itemsite_loccntrl	:= FALSE;
    _new.itemsite_safetystock	:= 0;
    _new.itemsite_minordqty	:= 0;
    _new.itemsite_multordqty	:= 0;
    _new.itemsite_leadtime	:= 0;
    _new.itemsite_controlmethod	:= 'R';
    IF(_new.itemsite_costmethod='N') THEN
      _new.itemsite_costmethod := 'S';
    END IF;
    _new.itemsite_active	:= TRUE;
    -- ? _new.itemsite_plancode_id	:= -1;
    -- ? _new.itemsite_costcat_id	:= -1;
    _new.itemsite_eventfence	:= 1;
    _new.itemsite_sold		:= FALSE;
    _new.itemsite_stocked	:= FALSE;
    _new.itemsite_location_id	:= -1;
    _new.itemsite_useparams	:= FALSE;
    _new.itemsite_useparamsmanual := FALSE;
    _new.itemsite_createpr	:= FALSE;
    _new.itemsite_location	:= NULL;
    _new.itemsite_location_comments := NULL;
    _new.itemsite_notes		:= 'Transit Warehouse';
    _new.itemsite_nnqoh		:= 0;
    _new.itemsite_createwo	:= FALSE;
    _new.itemsite_costcat_id	:= _destwhs.warehous_costcat_id;
  END IF;

  INSERT INTO itemsite (
    itemsite_id,			itemsite_item_id,
    itemsite_warehous_id,		itemsite_qtyonhand,
    itemsite_costmethod,                itemsite_value,
    itemsite_reorderlevel,		itemsite_ordertoqty,
    itemsite_cyclecountfreq,		itemsite_datelastcount,
    itemsite_datelastused,
    itemsite_posupply,			itemsite_wosupply,
    itemsite_loccntrl,
    itemsite_safetystock,		itemsite_minordqty,
    itemsite_multordqty,		itemsite_leadtime,
    itemsite_abcclass,			itemsite_issuemethod,
    itemsite_controlmethod,		itemsite_active,
    itemsite_plancode_id,		itemsite_costcat_id,
    itemsite_eventfence,		itemsite_sold,
    itemsite_stocked,			itemsite_freeze,
    itemsite_location_id,
    itemsite_useparams,			itemsite_useparamsmanual,
    itemsite_soldranking,		itemsite_createpr,
    itemsite_location,			itemsite_location_comments,
    itemsite_notes,			itemsite_perishable,
    itemsite_nnqoh,			itemsite_autoabcclass,
    itemsite_ordergroup,		itemsite_disallowblankwip,
    itemsite_maxordqty,			itemsite_mps_timefence,
    itemsite_createwo,			itemsite_warrpurc,
    itemsite_autoreg,
    itemsite_planning_type,             itemsite_supply_itemsite_id
  ) VALUES (
    _new.itemsite_id,			_new.itemsite_item_id,
    _new.itemsite_warehous_id,		_new.itemsite_qtyonhand,
    _new.itemsite_costmethod,           _new.itemsite_value,
    _new.itemsite_reorderlevel,	        _new.itemsite_ordertoqty,
    _new.itemsite_cyclecountfreq,	_new.itemsite_datelastcount,
    _new.itemsite_datelastused,
    _new.itemsite_posupply,		_new.itemsite_wosupply,
    _new.itemsite_loccntrl,
    _new.itemsite_safetystock,		_new.itemsite_minordqty,
    _new.itemsite_multordqty,		_new.itemsite_leadtime,
    _new.itemsite_abcclass,		_new.itemsite_issuemethod,
    _new.itemsite_controlmethod,	_new.itemsite_active,
    _new.itemsite_plancode_id,		_new.itemsite_costcat_id,
    _new.itemsite_eventfence,		_new.itemsite_sold,
    _new.itemsite_stocked,		_new.itemsite_freeze,
    _new.itemsite_location_id,
    _new.itemsite_useparams,		_new.itemsite_useparamsmanual,
    _new.itemsite_soldranking,		_new.itemsite_createpr,
    _new.itemsite_location,		_new.itemsite_location_comments,
    _new.itemsite_notes,		_new.itemsite_perishable,
    _new.itemsite_nnqoh,		_new.itemsite_autoabcclass,
    _new.itemsite_ordergroup,		_new.itemsite_disallowblankwip,
    _new.itemsite_maxordqty,		_new.itemsite_mps_timefence,
    _new.itemsite_createwo,   	        _new.itemsite_warrpurc,
    _new.itemsite_autoreg,
    _new.itemsite_planning_type,        _new.itemsite_supply_itemsite_id
    );

  RETURN _new.itemsite_id;
END;

Function: public.copylocale(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocaleid ALIAS FOR $1;
  _localeid INTEGER;

BEGIN

  SELECT NEXTVAL('locale_locale_id_seq') INTO _localeid;

  INSERT INTO locale
        (locale_id, locale_code, locale_descrip,
         locale_lang_file,
         locale_dateformat,
         locale_currformat,
         locale_qtyformat,
         locale_comments,
         locale_qtyperformat,
         locale_salespriceformat,
         locale_extpriceformat,
         locale_timeformat,
         locale_timestampformat,
         local_costformat,
         locale_costformat,
         locale_purchpriceformat,
         locale_uomratioformat,
         locale_intervalformat,
         locale_lang_id,
         locale_country_id,
         locale_error_color,
         locale_warning_color,
         locale_emphasis_color,
         locale_altemphasis_color,
         locale_expired_color,
         locale_future_color,
         locale_curr_scale,
         locale_salesprice_scale,
         locale_purchprice_scale,
         locale_extprice_scale,
         locale_cost_scale,
         locale_qty_scale,
         locale_qtyper_scale,
         locale_uomratio_scale)
  SELECT _localeid, '', '',
         locale_lang_file,
         locale_dateformat,
         locale_currformat,
         locale_qtyformat,
         locale_comments,
         locale_qtyperformat,
         locale_salespriceformat,
         locale_extpriceformat,
         locale_timeformat,
         locale_timestampformat,
         local_costformat,
         locale_costformat,
         locale_purchpriceformat,
         locale_uomratioformat,
         locale_intervalformat,
         locale_lang_id,
         locale_country_id,
         locale_error_color,
         locale_warning_color,
         locale_emphasis_color,
         locale_altemphasis_color,
         locale_expired_color,
         locale_future_color,
         locale_curr_scale,
         locale_salesprice_scale,
         locale_purchprice_scale,
         locale_extprice_scale,
         locale_cost_scale,
         locale_qty_scale,
         locale_qtyper_scale,
         locale_uomratio_scale
    FROM locale
   WHERE(locale_id=pLocaleid);

  RETURN _localeid;

END;

Function: public.copypo(integer, integer, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSrcid		ALIAS FOR $1;
  pVendid		ALIAS FOR $2;
  pOrderdate		ALIAS FOR $3;
  pRecheckVendinfo	ALIAS FOR $4;

  _tgtid		INTEGER;
  _orderdate		DATE;
  _head			RECORD;
  _itemsrc		RECORD;
  _lineitem		RECORD;
  _qty			NUMERIC;
  _unitprice		NUMERIC;
  _uomratio		NUMERIC;
  _vend_restrictpurch	BOOLEAN;

BEGIN
  SELECT * INTO _head FROM pohead WHERE pohead_id = pSrcid;
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;
  IF (_head.pohead_vend_id != pVendid) THEN
    RETURN -2;		-- not supported now but should be in the future
  END IF;		-- when enabled, set pRecheckVendinfo if vendors don't match

  IF (pOrderdate IS NULL) THEN
    _orderdate := CURRENT_DATE;
  ELSE
    _orderdate := pOrderdate;
  END IF;

  INSERT INTO pohead (pohead_status, pohead_number,
		      pohead_orderdate, pohead_vend_id,
		      pohead_fob, pohead_shipvia,
		      pohead_freight, pohead_printed,
		      pohead_terms_id, pohead_warehous_id,
		      pohead_vendaddr_id, pohead_agent_username,
		      pohead_curr_id, pohead_saved,
                      pohead_taxtype_id, pohead_taxzone_id,
                      pohead_dropship, pohead_vend_cntct_id,
                      pohead_vend_cntct_honorific, pohead_vend_cntct_first_name,
                      pohead_vend_cntct_middle, pohead_vend_cntct_last_name,
                      pohead_vend_cntct_suffix, pohead_vend_cntct_phone,
                      pohead_vend_cntct_title, pohead_vend_cntct_fax,
                      pohead_vend_cntct_email, pohead_vendaddress1,
                      pohead_vendaddress2, pohead_vendaddress3,
                      pohead_vendcity, pohead_vendstate,
                      pohead_vendzipcode, pohead_vendcountry,
                      pohead_shipto_cntct_id,
                      pohead_shipto_cntct_honorific, pohead_shipto_cntct_first_name,
                      pohead_shipto_cntct_middle, pohead_shipto_cntct_last_name,
                      pohead_shipto_cntct_suffix, pohead_shipto_cntct_phone,
                      pohead_shipto_cntct_title, pohead_shipto_cntct_fax,
                      pohead_shipto_cntct_email, pohead_shiptoaddress_id,
                      pohead_shiptoaddress1,
                      pohead_shiptoaddress2, pohead_shiptoaddress3,
                      pohead_shiptocity, pohead_shiptostate,
                      pohead_shiptozipcode, pohead_shiptocountry
	      ) VALUES (
		      'U', fetchPoNumber(),
		      _orderdate, _head.pohead_vend_id,
		      _head.pohead_fob, _head.pohead_shipvia,
		      _head.pohead_freight, false,
		      _head.pohead_terms_id, _head.pohead_warehous_id,
		      _head.pohead_vendaddr_id, _head.pohead_agent_username,
		      _head.pohead_curr_id, true,
                      _head.pohead_taxtype_id, _head.pohead_taxzone_id,
                      false, _head.pohead_vend_cntct_id,
                      _head.pohead_vend_cntct_honorific, _head.pohead_vend_cntct_first_name,
                      _head.pohead_vend_cntct_middle, _head.pohead_vend_cntct_last_name,
                      _head.pohead_vend_cntct_suffix, _head.pohead_vend_cntct_phone,
                      _head.pohead_vend_cntct_title, _head.pohead_vend_cntct_fax,
                      _head.pohead_vend_cntct_email, _head.pohead_vendaddress1,
                      _head.pohead_vendaddress2, _head.pohead_vendaddress3,
                      _head.pohead_vendcity, _head.pohead_vendstate,
                      _head.pohead_vendzipcode, _head.pohead_vendcountry,
                      _head.pohead_shipto_cntct_id,
                      _head.pohead_shipto_cntct_honorific, _head.pohead_shipto_cntct_first_name,
                      _head.pohead_shipto_cntct_middle, _head.pohead_shipto_cntct_last_name,
                      _head.pohead_shipto_cntct_suffix, _head.pohead_shipto_cntct_phone,
                      _head.pohead_shipto_cntct_title, _head.pohead_shipto_cntct_fax,
                      _head.pohead_shipto_cntct_email, _head.pohead_shiptoaddress_id,
                      _head.pohead_shiptoaddress1,
                      _head.pohead_shiptoaddress2, _head.pohead_shiptoaddress3,
                      _head.pohead_shiptocity, _head.pohead_shiptostate,
                      _head.pohead_shiptozipcode, _head.pohead_shiptocountry);

  _tgtid := CURRVAL('pohead_pohead_id_seq');

  IF (pRecheckVendinfo) THEN
    SELECT vend_restrictpurch INTO _vend_restrictpurch
      FROM vendinfo WHERE (vend_id = pVendid);

    FOR _lineitem IN SELECT *
		  FROM poitem 
		  WHERE (poitem_pohead_id = pSrcid) LOOP

      SELECT * INTO _itemsrc
      FROM itemsrc, itemsite
      WHERE (itemsrc_active
        AND  (itemsrc_id = _lineitem.poitem_itemsrc_id)
	AND  (itemsite_id = _lineitem.poitem_itemsite_id));
      IF (NOT FOUND AND _vend_restrictpurch) THEN
	RETURN -3;
      END IF;

      -- handle changes to the uom ratio and consequent qty changes
      _uomratio := COALESCE(_itemsrc.itemsrc_invvendoruomratio, _lineitem.poitem_invvenduomratio);
      IF (_itemsrc.itemsrc_invvendoruomratio IS NULL
	  OR _itemsrc.itemsrc_invvendoruomratio != _lineitem.poitem_invvenduomratio) THEN
	_qty := _lineitem.poitem_qty_ordered;

      ELSE
	_qty := _lineitem.poitem_qty_ordered * _lineitem.poitem_invvenduomratio /
					       _itemsrc.itemsrc_invvendoruomratio;
	IF (_itemsrc.itemsrc_minordqty IS NOT NULL) THEN
	  IF (_qty < _itemsrc.itemsrc_minordqty) THEN
	    _qty := _itemsrc.itemsrc_minordqty;
	  ELSIF (_itemsrc.itemsrc_multordqty > 0
		   AND _qty % _itemsrc.itemsrc_multordqty > 0) THEN
	    _qty = _qty % _itemsrc.itemsrc_multordqty + _itemsrc.itemsrc_multordqty;
	  END IF;
	END IF;
      END IF;

      IF (_itemsrc.itemsrc_id IS NULL) THEN
	_unitprice = _lineitem.poitem_unitprice;
      ELSE
	SELECT currToCurr(itemsrcp_curr_id, _head.pohead_curr_id,
			  itemsrcp_price, _orderdate) INTO _unitprice
	FROM itemsrcp
	WHERE ((itemsrcp_itemsrc_id = _itemsrc.itemsrc_id)
	  AND  (itemsrcp_qtybreak <= _lineitem.poitem_qty_ordered))
	ORDER BY itemsrcp_qtybreak DESC
	LIMIT 1;
	IF (_unitprice IS NULL) THEN
	  RETURN -4;
	END IF;
      END IF;

      INSERT INTO poitem (poitem_status, poitem_pohead_id, poitem_linenumber,
			  poitem_duedate,
			  poitem_itemsite_id,
			  poitem_vend_item_descrip,
			  poitem_vend_uom,
			  poitem_invvenduomratio,
			  poitem_qty_ordered, poitem_unitprice,
			  poitem_vend_item_number,
			  poitem_comments, poitem_expcat_id,
			  poitem_itemsrc_id,
			  poitem_freight,
			  poitem_stdcost,
			  poitem_manuf_name,
			  poitem_manuf_item_number,
			  poitem_manuf_item_descrip,
                          poitem_taxtype_id
		    ) VALUES (
			  'U', _tgtid, _lineitem.poitem_linenumber,
			  _orderdate + COALESCE(_itemsrc.itemsrc_leadtime, 0),
			  _lineitem.poitem_itemsite_id,
			  COALESCE(_itemsrc.itemsrc_vend_item_descrip,
				   _lineitem.poitem_vend_item_descrip),
			  COALESCE(_itemsrc.itemsrc_vend_uom, _lineitem.poitem_vend_uom),
			  COALESCE(_itemsrc.itemsrc_invvendoruomratio,
				   _lineitem.poitem_invvenduomratio),
			  _qty, _unitprice,
			  COALESCE(_itemsrc.itemsrc_vend_item_number,
				   _lineitem.poitem_vend_item_number),
			  _lineitem.poitem_comments, _lineitem.poitem_expcat_id,
			  COALESCE(_itemsrc.itemsrc_id, -1),
			  _lineitem.poitem_freight,
			  stdcost(_itemsrc.itemsite_item_id),
			  COALESCE(_itemsrc.itemsrc_manuf_name,
				   _lineitem.poitem_manuf_name),
		          COALESCE(_itemsrc.itemsrc_manuf_item_number,
				   _lineitem.poitem_manuf_item_number),
			  COALESCE(_itemsrc.itemsrc_manuf_item_descrip,
				   _lineitem.poitem_manuf_item_descrip),
                          _lineitem.poitem_taxtype_id);

    END LOOP;
  ELSE
    INSERT INTO poitem (poitem_status, poitem_pohead_id, poitem_linenumber,
			poitem_duedate, poitem_itemsite_id,
			poitem_vend_item_descrip, poitem_vend_uom,
			poitem_invvenduomratio, poitem_qty_ordered,
			poitem_unitprice,
			poitem_vend_item_number, poitem_comments,
			poitem_expcat_id, poitem_itemsrc_id, poitem_freight,
			poitem_stdcost, poitem_manuf_name, 
			poitem_manuf_item_number, poitem_manuf_item_descrip,
                        poitem_taxtype_id
		) SELECT 'U', _tgtid, poitem_linenumber,
			_orderdate + COALESCE(itemsrc_leadtime, 0), poitem_itemsite_id,
			poitem_vend_item_descrip, poitem_vend_uom,
			poitem_invvenduomratio, poitem_qty_ordered,
			poitem_unitprice,
			poitem_vend_item_number, poitem_comments,
			poitem_expcat_id, poitem_itemsrc_id, poitem_freight,
			stdcost(itemsite_item_id), poitem_manuf_name,
			poitem_manuf_item_number, poitem_manuf_item_descrip,
                        poitem_taxtype_id
		  FROM poitem
		    LEFT OUTER JOIN itemsrc ON (itemsrc_id=poitem_itemsrc_id)
		    LEFT OUTER JOIN itemsite ON (itemsite_id=poitem_itemsite_id)
		  WHERE (poitem_pohead_id = pSrcid);
  END IF;

  -- Todo: recalculate tax?

  RETURN _tgtid;

END;

Function: public.copypricingschedule(pipsheadid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _ipsheadid INTEGER;
  _ipsitemid INTEGER;
  _ipsfreightid INTEGER;
  _x RECORD;

BEGIN

  _ipsheadid := nextval('ipshead_ipshead_id_seq');
  INSERT INTO ipshead 
  ( ipshead_id, ipshead_name, ipshead_descrip,
    ipshead_effective, ipshead_expires, 
    ipshead_curr_id, ipshead_updated ) 
  SELECT _ipsheadid, orig.ipshead_name || (SELECT CAST((COUNT(cnt.ipshead_id)+1) AS text)
				            FROM ipshead cnt
				            WHERE (SUBSTRING(cnt.ipshead_name FROM 0 FOR char_length(orig.ipshead_name)+1) = orig.ipshead_name)),
	 orig.ipshead_descrip, orig.ipshead_effective, orig.ipshead_expires, 
	 orig.ipshead_curr_id, CURRENT_DATE
  FROM ipshead orig
  WHERE (orig.ipshead_id=pIpsheadId);

  FOR _x IN
    SELECT ipsitem_id FROM ipsiteminfo WHERE (ipsitem_ipshead_id=pIpsheadid)
  LOOP 
      INSERT INTO ipsiteminfo 
          (ipsitem_ipshead_id, ipsitem_item_id, ipsitem_prodcat_id,
           ipsitem_qtybreak, ipsitem_price,
           ipsitem_qty_uom_id, ipsitem_price_uom_id,
           ipsitem_discntprcnt, ipsitem_fixedamtdiscount,
           ipsitem_type, ipsitem_warehous_id) 
      SELECT _ipsheadid, ipsitem_item_id, ipsitem_prodcat_id,
           ipsitem_qtybreak, ipsitem_price,
           ipsitem_qty_uom_id, ipsitem_price_uom_id,
           ipsitem_discntprcnt, ipsitem_fixedamtdiscount,
           ipsitem_type, ipsitem_warehous_id
      FROM ipsiteminfo 
      WHERE (ipsitem_id=_x.ipsitem_id)
      RETURNING ipsitem_id INTO _ipsitemid; 

      INSERT INTO ipsitemchar
        ( ipsitemchar_ipsitem_id, ipsitemchar_char_id,
          ipsitemchar_value, ipsitemchar_price)
      SELECT  _ipsitemid, ipsitemchar_char_id,
          ipsitemchar_value, ipsitemchar_price
      FROM ipsitemchar
      WHERE (ipsitemchar_ipsitem_id=_x.ipsitem_id);
  END LOOP;

  FOR _x IN
    SELECT ipsfreight_id FROM ipsfreight WHERE (ipsfreight_ipshead_id=pIpsheadid)
  LOOP 
      _ipsfreightid := nextval('ipsfreight_ipsfreight_id_seq');
      INSERT INTO ipsfreight
          (ipsfreight_id, ipsfreight_ipshead_id, 
           ipsfreight_qtybreak, ipsfreight_price,
           ipsfreight_type, ipsfreight_warehous_id,
           ipsfreight_shipzone_id,ipsfreight_freightclass_id,
           ipsfreight_shipvia) 
      SELECT _ipsfreightid, _ipsheadid, ipsfreight_qtybreak, 
           ipsfreight_price,ipsfreight_type, 
           ipsfreight_warehous_id,ipsfreight_shipzone_id,
           ipsfreight_freightclass_id,ipsfreight_shipvia
      FROM ipsfreight
      WHERE (ipsfreight_id=_x.ipsfreight_id); 

  END LOOP;

  RETURN _ipsheadid;

END;

Function: public.copyprj(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pparentid   ALIAS FOR $1;
  _counter    INTEGER;
  _duedate    DATE := COALESCE($2, CURRENT_DATE);
  _alarmid    INTEGER;
  _i          INTEGER;
  _newnumber  TEXT;
  _p          RECORD;
  _prjid      INTEGER;
  _testnumber TEXT;

BEGIN
  RAISE DEBUG 'copyPrj(%, %) entered', pparentid, _duedate;

  SELECT * INTO _p
  FROM prj
  WHERE (prj_id=pparentid);

  -- new number = old number up to but not including -, followed by _duedate
  -- e.g. REPAIR-FRIDGE becomes REPAIR-2010-05-15
  --  but REPAIR_FRIDGE becomes REPAIR_FRIDGE-2010-05-15
  IF (_p.prj_recurring_prj_id IS NULL) THEN
    _newnumber := _p.prj_number;
  ELSE
    _newnumber := SUBSTRING(_p.prj_number FROM '[^-]*');
    IF (_newnumber IS NULL) THEN
      _newnumber := _p.prj_number;
    END IF;
  END IF;
  _newnumber := _newnumber || '-' || to_char(_duedate, 'YYYY-MM-DD');
  
  RAISE DEBUG 'copyPrj checking if _newnumber % exists', _newnumber;
  SELECT MAX(prj_number) INTO _testnumber
    FROM prj
   WHERE (prj_number ~ ('^' || _newnumber));
  IF (_testnumber = _newnumber) THEN
    _newnumber := _newnumber || '-001';
  ELSIF (_testnumber IS NOT NULL) THEN
    _counter := CAST(SUBSTRING(_testnumber FROM '...$') AS INTEGER);
    _counter := _counter + 1;
    _newnumber := REGEXP_REPLACE(_testnumber, '...$', to_char(_counter, 'FM009'));
  END IF;
  RAISE DEBUG 'copyPrj _newnumber is now %', _newnumber;

  INSERT INTO prj(
            prj_number,     prj_name,           prj_descrip,
            prj_status,     prj_so,             prj_wo,
            prj_po,         prj_owner_username,
            prj_due_date,   prj_username,       prj_recurring_prj_id
  ) SELECT  _newnumber,     _p.prj_name,        _p.prj_descrip,
            'P',            _p.prj_so,          _p.prj_wo,
            _p.prj_po,      _p.prj_owner_username,
            _duedate,       _p.prj_username,    _p. prj_recurring_prj_id
      FROM prj
     WHERE (prj_id=pparentid)
  RETURNING prj_id INTO _prjid;

  IF (_prjid IS NULL) THEN
    RETURN -1;
  END IF;

  SELECT saveAlarm(NULL, NULL, _duedate,
                   CAST(alarm_time - DATE_TRUNC('day',alarm_time) AS TIME),
                   alarm_time_offset,
                   alarm_time_qualifier,
                   alarm_event_recipient  IS NOT NULL, alarm_event_recipient,
                   alarm_email_recipient  IS NOT NULL, alarm_email_recipient,
                   alarm_sysmsg_recipient IS NOT NULL, alarm_sysmsg_recipient,
                   'J', _prjid, 'CHANGEONE')
    INTO _alarmid
    FROM alarm
   WHERE ((alarm_source='J')
      AND (alarm_source_id=pparentid));

   IF (_alarmid < 0) THEN
     RETURN _alarmid;
   END IF;

  RETURN _prjid;
END;

Function: public.copyproject(integer, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjId ALIAS FOR $1;
  pPrjNumber ALIAS FOR $2;
  pDueDateOffset ALIAS FOR $3;
  _prjid INTEGER;

BEGIN

  IF (COALESCE(pPrjNumber, '') = '') THEN
    RETURN -1;
  END IF;

  IF (EXISTS(SELECT prj_id FROM prj WHERE UPPER(prj_number)=UPPER(pPrjNumber))) THEN
    RETURN -2;
  END IF;

  IF (NOT EXISTS(SELECT prj_id FROM prj WHERE prj_id=pPrjId)) THEN
    RETURN -3;
  END IF;

  SELECT NEXTVAL('prj_prj_id_seq') INTO _prjid;

  INSERT INTO prj
  ( prj_id, prj_number, prj_name, 
    prj_descrip, prj_status,
    prj_so, prj_wo, prj_po,
    prj_owner_username, prj_start_date,
    prj_due_date, prj_assigned_date, prj_completed_date,
    prj_username, prj_recurring_prj_id,
    prj_crmacct_id, prj_cntct_id )
  SELECT _prjid, UPPER(pPrjNumber), prj_name,
         prj_descrip, 'P',
         prj_so, prj_wo, prj_po,
         prj_owner_username, NULL,
         (prj_due_date + COALESCE(pDueDateOffset, 0)),
         CASE WHEN (prj_username IS NULL) THEN NULL ELSE CURRENT_DATE END, NULL,
         prj_username, prj_recurring_prj_id,
         prj_crmacct_id, prj_cntct_id
  FROM prj
  WHERE (prj_id=pPrjId);

  INSERT INTO prjtask
  ( prjtask_number, prjtask_name, prjtask_descrip,
    prjtask_prj_id, prjtask_anyuser, prjtask_status,
    prjtask_hours_budget, prjtask_hours_actual,
    prjtask_exp_budget, prjtask_exp_actual,
    prjtask_owner_username, prjtask_start_date,
    prjtask_due_date, prjtask_assigned_date,
    prjtask_completed_date, prjtask_username )
  SELECT prjtask_number, prjtask_name, prjtask_descrip,
         _prjid, prjtask_anyuser, 'P',
         prjtask_hours_budget, 0.0,
         prjtask_exp_budget, 0.0,
         prjtask_owner_username, NULL,
         (prjtask_due_date + COALESCE(pDueDateOffset, 0)),
         CASE WHEN (prjtask_username IS NULL) THEN NULL ELSE CURRENT_DATE END,
         NULL, prjtask_username
  FROM prjtask
  WHERE (prjtask_prj_id=pPrjId);

  INSERT INTO docass
  ( docass_source_id, docass_source_type,
    docass_target_id, docass_target_type,
    docass_purpose )
  SELECT _prjid, docass_source_type,
         docass_target_id, docass_target_type,
         docass_purpose
  FROM docass
  WHERE ((docass_source_id=pPrjId)
    AND  (docass_source_type='J'));

  RETURN _prjid;

END;

Function: public.copyquote(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  pSchedDate ALIAS FOR $2;
  _quheadid INTEGER;
  _qunumber TEXT;

BEGIN

  SELECT NEXTVAL('quhead_quhead_id_seq') INTO _quheadid;
  IF (fetchMetricText('QUNumberGeneration') = 'S') THEN
    SELECT fetchSoNumber() INTO _qunumber;
  ELSE
    SELECT fetchQuNumber() INTO _qunumber;
  END IF;

  INSERT INTO quhead
  ( quhead_id, quhead_number, quhead_cust_id, quhead_prj_id,
    quhead_quotedate, quhead_packdate, quhead_origin, quhead_fob,
    quhead_warehous_id, quhead_terms_id, quhead_salesrep_id,
    quhead_custponumber, quhead_shipvia,
    quhead_shipto_id, quhead_shiptoname, quhead_shiptoaddress1, quhead_shiptoaddress2, quhead_shiptoaddress3,
    quhead_shiptocity, quhead_shiptostate, quhead_shiptozipcode, quhead_shiptophone, quhead_shiptocountry,
    quhead_billtoname, quhead_billtoaddress1, quhead_billtoaddress2, quhead_billtoaddress3,
    quhead_billtocity, quhead_billtostate, quhead_billtozip,
    quhead_misc_accnt_id, quhead_misc_descrip, quhead_misc, quhead_freight, quhead_commission,
    quhead_ordercomments, quhead_shipcomments,
    quhead_imported, quhead_curr_id, quhead_taxzone_id, quhead_taxtype_id, quhead_ophead_id, quhead_status,
    quhead_shipto_cntct_id, quhead_shipto_cntct_honorific, quhead_shipto_cntct_first_name, quhead_shipto_cntct_middle,
    quhead_shipto_cntct_last_name, quhead_shipto_cntct_suffix, quhead_shipto_cntct_phone, quhead_shipto_cntct_title,
    quhead_shipto_cntct_fax, quhead_shipto_cntct_email, quhead_billto_cntct_id, quhead_billto_cntct_honorific,
    quhead_billto_cntct_first_name, quhead_billto_cntct_middle, quhead_billto_cntct_last_name, quhead_billto_cntct_suffix,
    quhead_billto_cntct_phone, quhead_billto_cntct_title, quhead_billto_cntct_fax, quhead_billto_cntct_email )
  SELECT _quheadid, _qunumber, quhead_cust_id, quhead_prj_id,
         CURRENT_DATE, COALESCE(pSchedDate, quhead_packdate), quhead_origin, quhead_fob,
         quhead_warehous_id, quhead_terms_id, quhead_salesrep_id,
         quhead_custponumber, quhead_shipvia,
         quhead_shipto_id, quhead_shiptoname, quhead_shiptoaddress1, quhead_shiptoaddress2, quhead_shiptoaddress3,
         quhead_shiptocity, quhead_shiptostate, quhead_shiptozipcode, quhead_shiptophone, quhead_shiptocountry,
         quhead_billtoname, quhead_billtoaddress1, quhead_billtoaddress2, quhead_billtoaddress3,
         quhead_billtocity, quhead_billtostate, quhead_billtozip,
         quhead_misc_accnt_id, quhead_misc_descrip, quhead_misc, quhead_freight, quhead_commission,
         quhead_ordercomments, quhead_shipcomments,
         FALSE, quhead_curr_id, quhead_taxzone_id, quhead_taxtype_id, quhead_ophead_id, 'O',
         quhead_shipto_cntct_id, quhead_shipto_cntct_honorific, quhead_shipto_cntct_first_name, quhead_shipto_cntct_middle,
         quhead_shipto_cntct_last_name, quhead_shipto_cntct_suffix, quhead_shipto_cntct_phone, quhead_shipto_cntct_title,
         quhead_shipto_cntct_fax, quhead_shipto_cntct_email, quhead_billto_cntct_id, quhead_billto_cntct_honorific,
         quhead_billto_cntct_first_name, quhead_billto_cntct_middle, quhead_billto_cntct_last_name, quhead_billto_cntct_suffix,
         quhead_billto_cntct_phone, quhead_billto_cntct_title, quhead_billto_cntct_fax, quhead_billto_cntct_email
  FROM quhead
  WHERE (quhead_id=pQuheadid);

  INSERT INTO quitem
  ( quitem_quhead_id, quitem_linenumber, quitem_itemsite_id,
    quitem_scheddate, quitem_promdate, quitem_qtyord,
    quitem_price, quitem_custprice, quitem_unitcost,
    quitem_qty_uom_id, quitem_price_uom_id,
    quitem_qty_invuomratio, quitem_price_invuomratio,
    quitem_memo, quitem_custpn, quitem_imported, quitem_taxtype_id,
    quitem_createorder, quitem_order_warehous_id, quitem_item_id, quitem_prcost )
  SELECT _quheadid, quitem_linenumber, quitem_itemsite_id,
         COALESCE(pSchedDate, quitem_scheddate),
         quitem_promdate,
         quitem_qtyord,
         quitem_price, quitem_custprice, stdCost(itemsite_item_id),
         quitem_qty_uom_id, quitem_price_uom_id,
         quitem_qty_invuomratio, quitem_price_invuomratio,
         quitem_memo, quitem_custpn, FALSE, quitem_taxtype_id,
         quitem_createorder, quitem_order_warehous_id, quitem_item_id, quitem_prcost
  FROM quitem, itemsite
  WHERE ( (quitem_itemsite_id=itemsite_id)
   AND (quitem_quhead_id=pQuheadid));

  INSERT INTO charass
        (charass_target_type, charass_target_id,
         charass_char_id, charass_value)
  SELECT charass_target_type, b.quitem_id,
         charass_char_id, charass_value
    FROM quitem a, charass, quitem b
   WHERE ((charass_target_type='SI')
     AND  (charass_target_id=a.quitem_id)
     AND  (a.quitem_quhead_id=pQuheadid)
     AND  (b.quitem_quhead_id=_quheadid)
     AND  (a.quitem_linenumber=b.quitem_linenumber)
     );

  RETURN _quheadid;

END;

Function: public.copyso(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  pSchedDate ALIAS FOR $2;
  _soheadid INTEGER;

BEGIN

  SELECT NEXTVAL('cohead_cohead_id_seq') INTO _soheadid;

  INSERT INTO cohead
  ( cohead_id,
    cohead_number,
    cohead_cust_id,
    cohead_custponumber,
    cohead_type,
    cohead_orderdate,
    cohead_warehous_id,
    cohead_shipto_id,
    cohead_shiptoname,
    cohead_shiptoaddress1,
    cohead_shiptoaddress2,
    cohead_shiptoaddress3,
    cohead_shiptoaddress4,
    cohead_shiptoaddress5,
    cohead_salesrep_id,
    cohead_terms_id,
    cohead_origin,
    cohead_fob,
    cohead_shipvia,
    cohead_shiptocity,
    cohead_shiptostate,
    cohead_shiptozipcode,
    cohead_freight,
    cohead_misc,
    cohead_imported,
    cohead_ordercomments,
    cohead_shipcomments,
    cohead_shiptophone,
    cohead_shipchrg_id,
    cohead_shipform_id,
    cohead_billtoname,
    cohead_billtoaddress1,
    cohead_billtoaddress2,
    cohead_billtoaddress3,
    cohead_billtocity,
    cohead_billtostate,
    cohead_billtozipcode,
    cohead_misc_accnt_id,
    cohead_misc_descrip,
    cohead_commission,
    cohead_miscdate,
    cohead_holdtype,
    cohead_packdate,
    cohead_prj_id,
    cohead_wasquote,
    cohead_lastupdated,
    cohead_shipcomplete,
    cohead_created,
    cohead_creator,
    cohead_quote_number,
    cohead_billtocountry,
    cohead_shiptocountry,
    cohead_curr_id,
    cohead_calcfreight,
    cohead_shipto_cntct_id,
    cohead_shipto_cntct_honorific,
    cohead_shipto_cntct_first_name,
    cohead_shipto_cntct_middle,
    cohead_shipto_cntct_last_name,
    cohead_shipto_cntct_suffix,
    cohead_shipto_cntct_phone,
    cohead_shipto_cntct_title,
    cohead_shipto_cntct_fax,
    cohead_shipto_cntct_email,
    cohead_billto_cntct_id,
    cohead_billto_cntct_honorific,
    cohead_billto_cntct_first_name,
    cohead_billto_cntct_middle,
    cohead_billto_cntct_last_name,
    cohead_billto_cntct_suffix,
    cohead_billto_cntct_phone,
    cohead_billto_cntct_title,
    cohead_billto_cntct_fax,
    cohead_billto_cntct_email,
    cohead_taxzone_id,
    cohead_taxtype_id,
    cohead_ophead_id,
    cohead_status,
    cohead_saletype_id,
    cohead_shipzone_id )
  SELECT
    _soheadid,
    fetchSoNumber(),
    cohead_cust_id,
    cohead_custponumber,
    cohead_type,
    CURRENT_DATE,
    cohead_warehous_id,
    cohead_shipto_id,
    cohead_shiptoname,
    cohead_shiptoaddress1,
    cohead_shiptoaddress2,
    cohead_shiptoaddress3,
    cohead_shiptoaddress4,
    cohead_shiptoaddress5,
    cohead_salesrep_id,
    cohead_terms_id,
    cohead_origin,
    cohead_fob,
    cohead_shipvia,
    cohead_shiptocity,
    cohead_shiptostate,
    cohead_shiptozipcode,
    cohead_freight,
    cohead_misc,
    FALSE,
    cohead_ordercomments,
    cohead_shipcomments,
    cohead_shiptophone,
    cohead_shipchrg_id,
    cohead_shipform_id,
    cohead_billtoname,
    cohead_billtoaddress1,
    cohead_billtoaddress2,
    cohead_billtoaddress3,
    cohead_billtocity,
    cohead_billtostate,
    cohead_billtozipcode,
    cohead_misc_accnt_id,
    cohead_misc_descrip,
    cohead_commission,
    cohead_miscdate,
    cohead_holdtype,
    COALESCE(pSchedDate, cohead_packdate),
    cohead_prj_id,
    FALSE,
    cohead_lastupdated,
    cohead_shipcomplete,
    NULL,
    getEffectiveXtUser(),
    NULL,
    cohead_billtocountry,
    cohead_shiptocountry,
    cohead_curr_id,
    cohead_calcfreight,
    cohead_shipto_cntct_id,
    cohead_shipto_cntct_honorific,
    cohead_shipto_cntct_first_name,
    cohead_shipto_cntct_middle,
    cohead_shipto_cntct_last_name,
    cohead_shipto_cntct_suffix,
    cohead_shipto_cntct_phone,
    cohead_shipto_cntct_title,
    cohead_shipto_cntct_fax,
    cohead_shipto_cntct_email,
    cohead_billto_cntct_id,
    cohead_billto_cntct_honorific,
    cohead_billto_cntct_first_name,
    cohead_billto_cntct_middle,
    cohead_billto_cntct_last_name,
    cohead_billto_cntct_suffix,
    cohead_billto_cntct_phone,
    cohead_billto_cntct_title,
    cohead_billto_cntct_fax,
    cohead_billto_cntct_email,
    cohead_taxzone_id,
    cohead_taxtype_id,
    cohead_ophead_id,
    cohead_status,
    cohead_saletype_id,
    cohead_shipzone_id
  FROM cohead
  WHERE (cohead_id=pSoheadid);

  INSERT INTO coitem
  ( coitem_cohead_id,
    coitem_linenumber,
    coitem_itemsite_id,
    coitem_status,
    coitem_scheddate,
    coitem_promdate,
    coitem_qtyord,
    coitem_unitcost,
    coitem_price,
    coitem_custprice,
    coitem_qtyshipped,
    coitem_order_id,
    coitem_memo,
    coitem_imported,
    coitem_qtyreturned,
    coitem_closedate,
    coitem_custpn,
    coitem_order_type,
    coitem_close_username,
--    coitem_lastupdated,
    coitem_substitute_item_id,
    coitem_created,
    coitem_creator,
    coitem_prcost,
    coitem_qty_uom_id,
    coitem_qty_invuomratio,
    coitem_price_uom_id,
    coitem_price_invuomratio,
    coitem_warranty,
    coitem_cos_accnt_id,
    coitem_qtyreserved,
    coitem_subnumber,
    coitem_firm,
    coitem_taxtype_id )
  SELECT
    _soheadid,
    coitem_linenumber,
    coitem_itemsite_id,
    'O',
    COALESCE(pSchedDate, coitem_scheddate),
    coitem_promdate,
    coitem_qtyord,
    stdCost(itemsite_item_id),
    coitem_price,
    coitem_custprice,
    0.0,
    -1,
    coitem_memo,
    FALSE,
    0.0,
    NULL,
    coitem_custpn,
    coitem_order_type,
    NULL,
--    NULL,
    coitem_substitute_item_id,
    NULL,
    getEffectiveXtUser(),
    coitem_prcost,
    coitem_qty_uom_id,
    coitem_qty_invuomratio,
    coitem_price_uom_id,
    coitem_price_invuomratio,
    coitem_warranty,
    coitem_cos_accnt_id,
    0.0,
    coitem_subnumber,
    coitem_firm,
    coitem_taxtype_id
  FROM coitem, itemsite
  WHERE ( (coitem_itemsite_id=itemsite_id)
   AND (coitem_status <> 'X')
   AND (coitem_cohead_id=pSoheadid)
   AND (coitem_subnumber = 0) );

  INSERT INTO charass
        (charass_target_type, charass_target_id,
         charass_char_id, charass_value)
  SELECT charass_target_type, b.coitem_id,
         charass_char_id, charass_value
    FROM coitem a, charass, coitem b
   WHERE ((charass_target_type='SI')
     AND  (charass_target_id=a.coitem_id)
     AND  (a.coitem_cohead_id=pSoheadid)
     AND  (b.coitem_cohead_id=_soheadid)
     AND  (a.coitem_linenumber=b.coitem_linenumber)
     AND  (a.coitem_subnumber=b.coitem_subnumber));

  RETURN _soheadid;

END;

Function: public.copytodoitem(integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pparentid   ALIAS FOR $1;
  _duedate    DATE := COALESCE($2, CURRENT_DATE);
  pincdtid    ALIAS FOR $3;
  _alarmid    INTEGER;
  _todoitemid INTEGER;

BEGIN
  INSERT INTO todoitem(
            todoitem_name,      todoitem_description,
            todoitem_incdt_id,
            todoitem_creator_username,                  todoitem_status,
            todoitem_active,    todoitem_due_date,
            todoitem_assigned_date,
            todoitem_seq,       todoitem_notes,         todoitem_crmacct_id,
            todoitem_ophead_id, todoitem_owner_username,todoitem_priority_id,
            todoitem_username,  todoitem_recurring_todoitem_id
  ) SELECT  todoitem_name,      todoitem_description,
            CASE WHEN pincdtid IS NULL THEN todoitem_incdt_id ELSE pincdtid END,
            getEffectiveXtUser(),                               'N',
            TRUE,               _duedate,
            CASE WHEN (todoitem_username IS NOT NULL) THEN CURRENT_DATE
                 ELSE NULL
            END,
            todoitem_seq,       todoitem_notes,         todoitem_crmacct_id,
            todoitem_ophead_id, todoitem_owner_username,todoitem_priority_id,
            todoitem_username,  todoitem_recurring_todoitem_id
      FROM todoitem
     WHERE (todoitem_id=pparentid)
  RETURNING todoitem_id INTO _todoitemid;

  IF (_todoitemid IS NULL) THEN
    RETURN -10;
  END IF;

  SELECT saveAlarm(NULL, NULL, _duedate,
                   CAST(alarm_time - DATE_TRUNC('day',alarm_time) AS TIME),
                   alarm_time_offset,
                   alarm_time_qualifier,
                   alarm_event_recipient  IS NOT NULL, alarm_event_recipient,
                   alarm_email_recipient  IS NOT NULL, alarm_email_recipient,
                   alarm_sysmsg_recipient IS NOT NULL, alarm_sysmsg_recipient,
                   'TODO', _todoitemid, 'CHANGEONE')
    INTO _alarmid
    FROM alarm
   WHERE ((alarm_source='TODO')
      AND (alarm_source_id=pparentid));

   IF (_alarmid < 0) THEN
     RETURN _alarmid;
   END IF;

  RETURN _todoitemid;
END;

Function: public.copyvoucher(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoheadid ALIAS FOR $1;
  _voheadid INTEGER;
  _vonumber TEXT;
  _vodate DATE := COALESCE($2, CURRENT_DATE);
  _i RECORD;
  _l RECORD;
  _vodistid INTEGER;

BEGIN
  SELECT *
    INTO _i
    FROM vohead
   WHERE(vohead_id=pVoheadid);
  IF(NOT FOUND) THEN
    RETURN -1;
  END IF;

  _vonumber := fetchVoNumber();
  _voheadid := nextval('vohead_vohead_id_seq');

  INSERT INTO vohead
        (vohead_id,
         vohead_number, vohead_pohead_id,
         vohead_posted, vohead_duedate,
         vohead_invcnumber, vohead_amount,
         vohead_docdate, vohead_1099,
         vohead_distdate, vohead_reference,
         vohead_terms_id, vohead_vend_id,
         vohead_curr_id, vohead_adjtaxtype_id,
         vohead_freighttaxtype_id, vohead_gldistdate,
         vohead_misc, vohead_taxzone_id,
         vohead_taxtype_id, vohead_notes,
         vohead_recurring_vohead_id )
  VALUES(_voheadid,
         _vonumber, _i.vohead_pohead_id,
         false, determineDueDate(_i.vohead_terms_id, _vodate),
         _i.vohead_invcnumber, _i.vohead_amount,
         _vodate, _i.vohead_1099,
         _vodate, _i.vohead_reference,
         _i.vohead_terms_id, _i.vohead_vend_id,
         _i.vohead_curr_id, _i.vohead_adjtaxtype_id,
         _i.vohead_freighttaxtype_id, _vodate,
         _i.vohead_misc, _i.vohead_taxzone_id,
         _i.vohead_taxtype_id, _i.vohead_notes,
         _i.vohead_recurring_vohead_id);

  FOR _l IN SELECT *
            FROM vodist
            WHERE (vodist_vohead_id=pVoheadid) LOOP
    SELECT NEXTVAL('vodist_vodist_id_seq') INTO _vodistid;

    INSERT INTO vodist
        (vodist_id, vodist_poitem_id,
         vodist_vohead_id, vodist_costelem_id,
         vodist_accnt_id, vodist_amount,
         vodist_qty, vodist_expcat_id,
         vodist_tax_id, vodist_discountable,
         vodist_notes)
    VALUES
        (_vodistid, _l.vodist_poitem_id,
         _voheadid, _l.vodist_costelem_id,
         _l.vodist_accnt_id, _l.vodist_amount,
         _l.vodist_qty, _l.vodist_expcat_id,
         _l.vodist_tax_id, _l.vodist_discountable,
         _l.vodist_notes);

  END LOOP;

  RETURN _voheadid;
END;

Function: public.correctporeceipt(integer, numeric, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPorecvid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pFreight ALIAS FOR $3;
  pItemlocSeries ALIAS FOR $4;

BEGIN
  RETURN correctReceipt('PO', $1, $2, $3, $4, NULL, NULL);
END;

Function: public.correctporeceipt(integer, numeric, numeric, integer, integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN correctReceipt('PO', $1, $2, $3, $4, $5, $6);
END;

Function: public.correctproduction(integer, numeric, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'correctProduction(INTEGER, NUMERIC, BOOLEAN, BOOLEAN) has been deprecated. Use corrrectProduction(INTEGER, NUMERIC, BOOLEAN, INTEGER) or a package-specific version instead.';
  RETURN  correctProduction($1, $2, $3, 0, now());
END;

Function: public.correctproduction(integer, numeric, boolean, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'correctProduction(INTEGER, NUMERIC, BOOLEAN, BOOLEAN, INTEGER) has been deprecated. Use corrrectProduction(INTEGER, NUMERIC, BOOLEAN, INTEGER) or a package-specific version instead.';
  RETURN correctProduction($1, $2, $3, $5, now());
END;

Function: public.correctproduction(integer, numeric, boolean, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid          ALIAS FOR $1;
  pQty           ALIAS FOR $2;
  pBackflush     ALIAS FOR $3;
  pItemlocSeries ALIAS FOR $4;
  pGlDistTS      ALIAS FOR $5;
BEGIN
  RETURN correctProduction($1, $2, $3, $4, $5, NULL);
END;

Function: public.correctproduction(integer, numeric, boolean, integer, timestamp with time zone, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid          ALIAS FOR $1;
  pQty           ALIAS FOR $2;
  pBackflush     ALIAS FOR $3;
  pItemlocSeries ALIAS FOR $4;
  pGlDistTS      ALIAS FOR $5;
  pInvhistId     ALIAS FOR $6;
  _invhistid        INTEGER;
  _itemlocSeries    INTEGER;
  _r                RECORD;
  _parentWIPAccntid INTEGER;
  _parentQty        NUMERIC;
  _qty              NUMERIC;
  _wipPost          NUMERIC;
  _sense            TEXT;
  _status           TEXT;
  _type             TEXT;
  _qtyfxd           NUMERIC := 0;

BEGIN

  -- Qty is positive for Assembly W/O
  -- Qty is negative for Disassembly W/O
  IF (pQty = 0) THEN
    RETURN pItemlocseries;
  ELSIF (pQty > 0) THEN
    _sense := 'from';
  ELSE
    _sense := 'to';
  END IF;

  SELECT item_type, roundQty(item_fractional, pQty), wo_status
    INTO _type, _parentQty, _status
    FROM wo JOIN itemsite ON (itemsite_id=wo_itemsite_id)
            JOIN item ON (item_id=itemsite_item_id)
   WHERE (wo_id=pWoid);
  
  IF (_status != 'I') THEN
    RETURN -1;
  END IF;

  IF (_type = 'J') THEN
    RETURN -2;
  END IF;

  IF (pItemlocSeries = 0) THEN
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  ELSE
    _itemlocSeries := pItemlocSeries;
  END IF;

  --  Calculate the WIP to correct 
  SELECT CASE WHEN (wo_cosmethod = 'D') THEN wo_postedvalue
              ELSE  round(((wo_postedvalue - wo_wipvalue) / wo_qtyrcv * _parentQty), 2)
         END INTO _wipPost
  FROM wo
  WHERE (wo_id=pWoid);

  --  Post the inventory transaction
  SELECT postInvTrans( itemsite_id, 'RM', (_parentQty * -1.0),
                       'W/O', 'WO', formatwonumber(pWoid), '',
                       ('Correct Receive Inventory ' || item_number || ' ' || _sense || ' Manufacturing'),
                       costcat_asset_accnt_id, getPrjAccntId(wo_prj_id, costcat_wip_accnt_id), _itemlocSeries, pGlDistTS,
                       (_wipPost * -1.0), -- only used when cost is average
                       pInvhistId) INTO _invhistid
  FROM wo JOIN itemsite ON (itemsite_id=wo_itemsite_id)
          JOIN item ON (item_id=itemsite_item_id)
          JOIN costcat ON (costcat_id=itemsite_costcat_id)
  WHERE (wo_id=pWoid);

  --  Decrease this W/O's qty. received and increase its WIP value
  UPDATE wo
  SET wo_qtyrcv = (wo_qtyrcv - _parentQty),
      wo_wipvalue = (wo_wipvalue + (CASE WHEN(itemsite_costmethod IN ('A','J'))
                                              THEN _wipPost
                                         WHEN(itemsite_costmethod='S')
                                              THEN stdcost(itemsite_item_id) * _parentQty
                                         ELSE 0.0 END))
  FROM itemsite
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (wo_id=pWoid) );

  IF (pBackflush) THEN
    FOR _r IN SELECT item_id, item_fractional,
                      itemsite_id, itemsite_warehous_id,
                      itemsite_controlmethod, itemsite_loccntrl,
                      itemsite_costmethod, 
                      wo_qtyrcv, wo_prj_id,
                      womatl_id, womatl_qtyfxd, womatl_qtyper,
                      womatl_scrap, womatl_issuemethod, womatl_uom_id
               FROM wo JOIN womatl ON (womatl_wo_id=wo_id AND womatl_issuemethod='L')
                       JOIN itemsite ON (itemsite_id=womatl_itemsite_id)
                       JOIN item ON (item_id=itemsite_item_id)
               WHERE (wo_id=pWoid) LOOP

      --  Cache the qty to be issued
      -- If going back to beginning, unissue fixed qty as well
      IF (_r.wo_qtyrcv - _parentQty > 0) THEN
        _qtyfxd := 0;
      ELSE
        _qtyfxd := _r.womatl_qtyfxd;
      END IF;
      
      _qty = roundQty(_r.item_fractional, (_qtyfxd + _parentQty * _r.womatl_qtyper) * (1 + _r.womatl_scrap));

      IF (_qty > 0) THEN
        SELECT returnWoMaterial(_r.womatl_id, _qty, _itemlocSeries, pGlDistTS) INTO _itemlocSeries;
      END IF;

    END LOOP;

  	--  BEGIN ROB Decrease this W/O's WIP value for custom costing
	  UPDATE wo
	  SET wo_wipvalue = (wo_wipvalue - (itemcost_stdcost * _parentQty)) 
	FROM costelem, itemcost, costcat, itemsite, item
	WHERE 
	  ((wo_id=pWoid) AND
	  (wo_itemsite_id=itemsite_id) AND
	  (itemsite_item_id=item_id) AND
	  (costelem_id = itemcost_costelem_id) AND
	  (itemcost_item_id = itemsite_item_id) AND
	  (itemsite_costcat_id = costcat_id) AND
	  (costelem_exp_accnt_id) IS NOT NULL  AND 
	  (costelem_sys = false));

	--  ROB Distribute to G/L - create Cost Variance, debit WIP
	  PERFORM insertGLTransaction( 'W/O', 'WO', formatwonumber(pWoid),
				       ('Correct Post Other Cost ' || item_number || ' ' || _sense || ' Manufacturing'),
				       getPrjAccntId(wo_prj_id, costelem_exp_accnt_id), 
				       getPrjAccntId(wo_prj_id, costcat_wip_accnt_id), _invhistid,
				       ((itemcost_stdcost * _parentQty)* -1),
				       CURRENT_DATE )
	FROM wo, costelem, itemcost, costcat, itemsite, item
	WHERE 
	  ((wo_id=pWoid) AND
	  (wo_itemsite_id=itemsite_id) AND
	  (itemsite_item_id=item_id) AND
	  (costelem_id = itemcost_costelem_id) AND
	  (itemcost_item_id = itemsite_item_id) AND
	  (itemsite_costcat_id = costcat_id) AND
	  (costelem_exp_accnt_id) IS NOT NULL  AND 
	  (costelem_sys = false));
	--End ROB

  END IF;

  RETURN _itemlocSeries;

END;

Function: public.correctreceipt(integer, numeric, numeric, integer, integer, date)

Returns: integer

Language: PLPGSQL

BEGIN
  RETURN correctReceipt($1, $2, $3, $4, $5, $6, NULL);
END;

Function: public.correctreceipt(integer, numeric, numeric, integer, integer, date, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  precvid		ALIAS FOR $1;
  pQty			ALIAS FOR $2;
  pFreight		ALIAS FOR $3;
  _itemlocSeries	INTEGER := COALESCE($4, 0);
  _currid		INTEGER := $5;
  pEffective		ALIAS FOR $6;
  pRecvCost		ALIAS FOR $7;
  _freight		NUMERIC;
  _qty			NUMERIC;
  _invhistid		INTEGER;
  _o			RECORD;
  _r			RECORD;
  _recvcost		NUMERIC;
  _tmp        INTEGER;
  _pricevar             NUMERIC := 0.00;
  _journalNumber INTEGER := fetchJournalNumber('GL-MISC');

BEGIN
  SELECT recv_qty, recv_date::DATE AS recv_date, recv_freight_curr_id,
	 recv_orderitem_id,
	 round(currToCurr(recv_freight_curr_id,
			  COALESCE(_currid, recv_freight_curr_id),
         recv_freight, recv_date::DATE),2) AS recv_freight,
         recv_posted, recv_order_type,
         COALESCE(itemsite_id, -1) AS itemsiteid,
	 itemsite_item_id, itemsite_costmethod,
	 (recv_splitfrom_id IS NOT NULL
	 OR (SELECT (count(*) > 0) 
	     FROM recv
	     WHERE (recv_splitfrom_id=recv_id))) AS split INTO _r
  FROM recv LEFT OUTER JOIN itemsite ON (recv_itemsite_id=itemsite_id)
  WHERE (recv_id=precvid);

  IF (NOT FOUND) THEN
    RETURN _itemlocSeries;
  END IF;

  IF (NOT _r.recv_order_type IN ('PO', 'RA', 'TO')) THEN
    RETURN -11;
  END IF;

  IF (_r.split) THEN
    RETURN -12;
  END IF;

  SELECT currToBase(orderitem_unitcost_curr_id, orderitem_unitcost,
		    _r.recv_date::DATE) AS unitprice_base,
	 orderhead_number, orderitem_linenumber,
	 orderhead_curr_id AS freight_curr_id,
	 orderitem_orderhead_type,
	 orderitem_qty_invuomratio INTO _o
  FROM orderhead, orderitem
  WHERE ((orderhead_id=orderitem_orderhead_id)
    AND  (orderhead_type=orderitem_orderhead_type)
    AND  (orderitem_id=_r.recv_orderitem_id)
    AND  (orderitem_orderhead_type=_r.recv_order_type));

  IF (NOT FOUND) THEN
    RETURN _itemlocSeries;
  END IF;

  -- Default to _o.orderitem_unitcost if recv_purchcost is not supplied
  -- Note: this should never happen, a value is always supplied
  if (pRecvCost IS NULL) THEN
    _recvcost := _o.orderitem_unitcost;
  ELSE
    -- Note: if the receipt has already been posted, pRecvCost will always 
    --       equal the original recv_purchcost (cannot be modified in GUI)
    _recvcost := pRecvCost; 
  END IF;

  IF (_r.recv_posted) THEN
    _qty := (pQty - _r.recv_qty);
    IF (_qty <> 0) THEN
      IF (_r.itemsiteid = -1) THEN
  PERFORM insertGLTransaction( _journalNumber,'S/R', _r.recv_order_type,
				      _o.orderhead_number,
				      'Receive Non-Inventory from ' ||
							    _r.recv_order_type,
				      expcat_liability_accnt_id,
				      getPrjAccntId(poitem_prj_id, expcat_exp_accnt_id), -1,
				      ROUND(_o.unitprice_base * _qty, 2),
				      pEffective )
	FROM poitem, expcat
	WHERE ((poitem_expcat_id=expcat_id)
	  AND  (poitem_id=_r.recv_orderitem_id)
	  AND  (_o.orderitem_orderhead_type='PO'));

	UPDATE recv
	SET recv_qty=pQty,
	    recv_value=(recv_value + ROUND(_o.unitprice_base * _qty, 2)),
            recv_date = pEffective
	WHERE (recv_id=precvid);

      ELSE
	IF (_itemlocSeries = 0 OR _itemlocSeries IS NULL) THEN
	  _itemlocSeries := NEXTVAL('itemloc_series_seq');
	END IF;

  SELECT postInvTrans( itemsite_id, 'RP',
			     (_qty * _o.orderitem_qty_invuomratio),
			     'S/R', _r.recv_order_type,
			     _o.orderhead_number::TEXT || '-' || _o.orderitem_linenumber::TEXT, '',
			     'Receive Inventory from ' || _r.recv_order_type,
			     costcat_asset_accnt_id,
			     costcat_liability_accnt_id,
			     _itemlocSeries, pEffective,
           ROUND(_recvcost * _qty, 2) -- alway passing since it is ignored if not average costed item
                           ) INTO _tmp
	FROM itemsite, costcat
	WHERE ((itemsite_costcat_id=costcat_id)
    AND  (itemsite_id=_r.itemsiteid) );

        IF(_r.itemsite_costmethod='A') THEN
	  UPDATE recv
	     SET recv_qty=pQty,
	         recv_value=(recv_value + _recvcost * _qty * _o.orderitem_qty_invuomratio),
                 recv_date = pEffective
	   WHERE(recv_id=precvid);
        ELSE
	  UPDATE recv
	     SET recv_qty=pQty,
	         recv_value=(recv_value + stdcost(_r.itemsite_item_id) * _qty * _o.orderitem_qty_invuomratio),
                 recv_date = pEffective
	   WHERE(recv_id=precvid);
        END IF;
    END IF;

      IF (_r.recv_order_type = 'PO') THEN
	UPDATE poitem
	SET poitem_qty_received=(poitem_qty_received + _qty)
	WHERE (poitem_id=_r.recv_orderitem_id);
      ELSIF (_r.recv_order_type = 'RA' AND fetchMetricBool('EnableReturnAuth')) THEN
	UPDATE raitem
	SET raitem_qtyreceived=(raitem_qtyreceived + _qty)
	WHERE (raitem_id=_r.recv_orderitem_id);
      ELSIF (_r.recv_order_type = 'TO' AND fetchMetricBool('MultiWhs')) THEN
	UPDATE toitem
	SET toitem_qty_received=(toitem_qty_received + _qty)
	WHERE (toitem_id=_r.recv_orderitem_id);
      END IF;

    END IF;

       IF (fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
         _invhistid := _tmp;
         -- Find the difference in the purchase price value expected from the P/O and the value of the transaction
         SELECT (((currToBase(pohead_curr_id,
         COALESCE(recv_purchcost, poitem_unitprice),
         recv_date::DATE)) * _qty) - (invhist_value_after - invhist_value_before)) INTO _pricevar
         FROM invhist, recv, pohead, poitem
         WHERE ((recv_orderitem_id=poitem_id)
           AND  (poitem_pohead_id=pohead_id)
           AND  (recv_id=precvid)
           AND  (invhist_id = _invhistid));

         -- If difference exists then
         IF (_pricevar <> 0.00) THEN
           -- Record an additional GL Transaction for the purchase price variance
           SELECT insertGLTransaction( _journalNumber,
                'S/R', _r.recv_order_type, _o.orderhead_number,
                                       'Purchase price variance adjusted for P/O ' || _o.orderhead_number || ' for item ' || _o.orderitem_linenumber::TEXT,
                                       costcat_liability_accnt_id,
                                       getPrjAccntId(poitem_prj_id, costcat_purchprice_accnt_id), -1,
                                       _pricevar,
                                       pEffective, false ) INTO _tmp
           FROM itemsite, costcat, poitem, recv
           WHERE ((itemsite_costcat_id=costcat_id)
              AND (recv_id=precvid)
              AND (recv_orderitem_id=poitem_id)
              AND (itemsite_id=recv_itemsite_id) );
           IF (NOT FOUND) THEN
             RAISE EXCEPTION 'Could not insert G/L transaction: no cost category found for itemsite_id %',
             _r.itemsite_id;
           ELSIF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
             RETURN _tmp;
           ELSE
             -- Posting to trial balance is deferred to prevent locking
             INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
             VALUES ( _tmp, _itemlocSeries );
           END IF;
         END IF;
       END IF;

    _freight := (pFreight - _r.recv_freight);
    IF (_freight <> 0) THEN

      IF (_r.itemsiteid = -1) THEN
  PERFORM insertGLTransaction( _journalNumber,'S/R', _r.recv_order_type,
				     _o.orderhead_number,
				    'Receive Non-Inventory Freight from ' || _r.recv_order_type,
             expcat_liability_accnt_id, getPrjAccntId(poitem_prj_id, expcat_freight_accnt_id), -1,
				      ROUND(currToBase(_currid, _freight,
						    pEffective), 2),
				     pEffective )
	FROM poitem, expcat
	WHERE ((poitem_expcat_id=expcat_id)
	  AND  (poitem_id=_r.recv_orderitem_id)
	  AND  (_r.recv_order_type='PO'));
      ELSE
  PERFORM insertGLTransaction(_journalNumber,'S/R', _r.recv_order_type,
				    _o.orderhead_number, 
				    'Receive Non-Inventory Freight from ' ||
							    _r.recv_order_type,
				   costcat_liability_accnt_id,
				   costcat_freight_accnt_id, -1,
				   round(currToBase(_currid, _freight,
						    pEffective), 2),
				   pEffective )
	FROM itemsite, costcat
	WHERE ( (itemsite_costcat_id=costcat_id)
	  AND   (itemsite_id=_r.itemsiteid) );
      END IF;

      IF (_r.recv_order_type = 'PO') THEN
	UPDATE poitem
	SET poitem_freight_received=(poitem_freight_received +
				   currToCurr(_currid, _o.freight_curr_id,
					      _freight, pEffective))
	WHERE (poitem_id=_r.recv_orderitem_id);

      -- raitem does not track freight

      ELSEIF (_r.recv_order_type = 'TO' AND fetchMetricBool('MultiWhs')) THEN
	UPDATE toitem
	SET toitem_freight_received=(toitem_freight_received +
				   currToCurr(_currid, _o.freight_curr_id,
					      _freight, pEffective))
	WHERE (toitem_id=_r.recv_orderitem_id);
      END IF;

      UPDATE recv
      SET recv_freight=currToCurr(_currid, recv_freight_curr_id, pFreight,
				  pEffective),
	  recv_date = pEffective
      WHERE (recv_id=precvid);
    END IF;

  ELSE

-- Receipt not posted yet
    UPDATE recv SET recv_qty=pQty, recv_freight=pFreight, recv_purchcost=_recvcost WHERE recv_id=precvid;
  END IF;

RETURN _itemlocSeries;

END;

Function: public.cosbycustomervalue(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  _value NUMERIC;
  _startDate DATE;
  _endDate DATE;

BEGIN

  _startDate := findPeriodStart(pPeriodid);
  _endDate := findPeriodEnd(pPeriodid);

-- Returns value in base currency
-- ToDo: is cohist_shipdate the right DATE to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitcost, cohist_shipdate)) INTO _value
  FROM cohist
  WHERE ( (cohist_cust_id=pCustid)
   AND (cohist_invcdate BETWEEN _startDate AND _endDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.costsbycustomerbyitemsite(integer, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPeriodid ALIAS FOR $3;
  _value NUMERIC;
  _startDate DATE;
  _endDate DATE;

BEGIN

  _startDate := findPeriodStart(pPeriodid);
  _endDate := findPeriodEnd(pPeriodid);

-- Returns value in base currency
-- ToDo: is cohist_shipdate the right DATE to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitcost, cohist_shipdate)) INTO _value
  FROM cohist
  WHERE ( (cohist_itemsite_id<>pItemsiteid)
   AND (cohist_cust_id=pCustid)
   AND (cohist_invcdate BETWEEN _startDate AND _endDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.costsbycustomervalue(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  _value NUMERIC;
  _startDate DATE;
  _endDate DATE;

BEGIN

  _startDate := findPeriodStart(pPeriodid);
  _endDate := findPeriodEnd(pPeriodid);

-- Returns value in base currency
-- ToDo: is cohist_shipdate the right DATE to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitcost, cohist_shipdate)) INTO _value
  FROM cohist
  WHERE ( (cohist_itemsite_id<>-1)
   AND (cohist_cust_id=pCustid)
   AND (cohist_invcdate BETWEEN _startDate AND _endDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.costsbycustomervalue(integer, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pProdcatid ALIAS FOR $3;
  _value NUMERIC;
  _startDate DATE;
  _endDate DATE;

BEGIN

  _startDate := findPeriodStart(pPeriodid);
  _endDate := findPeriodEnd(pPeriodid);

-- Returns value in base currency
-- ToDo: is cohist_shipdate the right DATE to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitcost, cohist_shipdate)) INTO _value
  FROM cohist, itemsite, item
  WHERE ( (cohist_cust_id=pCustid)
   AND (cohist_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (item_prodcat_id=pProdcatid)
   AND (cohist_invcdate BETWEEN _startDate AND _endDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.costsbycustomervalue(integer, integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pProdcat ALIAS FOR $3;
  _value NUMERIC;
  _startDate DATE;
  _endDate DATE;

BEGIN

  _startDate := findPeriodStart(pPeriodid);
  _endDate := findPeriodEnd(pPeriodid);

-- Returns value in base currency
-- ToDo: is cohist_shipdate the right date to use?
  SELECT SUM(cohist_qtyshipped * currToBase(cohist_curr_id, cohist_unitcost, cohist_shipdate)) INTO _value
  FROM cohist, itemsite, item, prodcat
  WHERE ( (cohist_cust_id=pCustid)
   AND (cohist_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (item_prodcat_id=prodcat_id)
   AND (prodcat_code ~ pProdcat)
   AND (cohist_invcdate BETWEEN _startDate AND _endDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.createaccountingperiod(date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStartDate ALIAS FOR $1;
  pEndDate ALIAS FOR $2;

BEGIN

  RETURN createAccountingPeriod(pStartDate, pEndDate, NULL, NULL);

END;

Function: public.createaccountingperiod(date, date, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStartDate ALIAS FOR $1;
  pEndDate ALIAS FOR $2;
  pYearPeriodId ALIAS FOR $3;
  pQuarter ALIAS FOR $4;
  _periodid INTEGER;
  _check INTEGER;
  _r RECORD;
  _initial BOOLEAN;
  _number INTEGER;

BEGIN

--  Make that the passed start date doesn't fall into any existing period
  SELECT period_id INTO _check
  FROM period
  WHERE (pStartDate BETWEEN period_start AND period_end);
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Make that the passed end date doesn't fall into any existing period
  SELECT period_id INTO _check
  FROM period
  WHERE (pEndDate BETWEEN period_start AND period_end);
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Make that the passed start and end dates don't enclose an existing period
  SELECT period_id INTO _check
  FROM period
  WHERE ( (period_start >= pStartDate)
   AND (period_end <= pEndDate) );
  IF (FOUND) THEN
    RETURN -3;
  END IF;

-- Make sure period is inside fiscal year
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE ((yearperiod_id=pYearPeriodId)
  AND (pStartDate>=yearperiod_start)
  AND (pEndDate<=yearperiod_end));
  IF NOT (FOUND) THEN
    RETURN -4;
  END IF;

--  Determine if this is the initial accounting period
  SELECT CASE WHEN(count(*) > 0) THEN FALSE
              ELSE TRUE
         END INTO _initial
  FROM period;

-- Determine the next number
  SELECT COALESCE(MAX(period_number),0) + 1 INTO _number
  FROM period
  WHERE (period_yearperiod_id=pYearPeriodId);

--  Create the new accounting period
  SELECT NEXTVAL('period_period_id_seq') INTO _periodid;
  INSERT INTO period
  ( period_id, period_start, period_end, period_closed, period_freeze, 
    period_initial, period_number, period_yearperiod_id, period_quarter )
  VALUES
  ( _periodid, pStartDate, pEndDate, FALSE, FALSE, _initial, _number, pYearPeriodId, pQuarter );

--  Post any unposted G/L Transactions into the new period
  FOR _r IN SELECT DISTINCT gltrans_sequence
            FROM gltrans
            WHERE ( (NOT gltrans_posted)
             AND (gltrans_date BETWEEN pStartDate AND pEndDate) ) LOOP
    PERFORM postIntoTrialBalance(_r.gltrans_sequence);
  END LOOP;

  RETURN _periodid;

END;

Function: public.createaccountingyearperiod(date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStartDate ALIAS FOR $1;
  pEndDate ALIAS FOR $2;
  _yearperiodid INTEGER;
  _check INTEGER;
  _checkBool BOOLEAN;
  _r RECORD;
  _initial BOOLEAN;

BEGIN

--  Make that the passed start date doesn't fall into any existing yearperiod
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE (pStartDate BETWEEN yearperiod_start AND yearperiod_end);
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Make that the passed end date doesn't fall into any existing yearperiod
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE (pEndDate BETWEEN yearperiod_start AND yearperiod_end);
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Make that the passed start and end dates don't enclose an existing yearperiod
  SELECT yearperiod_id INTO _check
  FROM yearperiod
  WHERE ( (yearperiod_start >= pStartDate)
   AND (yearperiod_end <= pEndDate) );
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Make sure that the passed start is prior to the end date
  SELECT (pStartDate > pEndDate) INTO _checkBool;
  IF (_checkBool) THEN
    RETURN -5;
  END IF;

--  Determine if this is the initial accounting yearperiod
  SELECT CASE WHEN(count(*) > 0) THEN FALSE
              ELSE TRUE
         END INTO _initial
  FROM yearperiod;

--  Create the new accounting yearperiod
  SELECT NEXTVAL('yearperiod_yearperiod_id_seq') INTO _yearperiodid;
  INSERT INTO yearperiod
  ( yearperiod_id, yearperiod_start, yearperiod_end, yearperiod_closed )
  VALUES
  ( _yearperiodid, pStartDate, pEndDate, FALSE );

  RETURN _yearperiodid;

END;

Function: public.createapchecks(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'createAPChecks() is deprecated - use createChecks() instead';
  RETURN createChecks($1, $2);
END;

Function: public.createapcreditmemo(integer, integer, integer, text, text, date, numeric, text, integer, date, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pId ALIAS FOR $1;
  pVendid ALIAS FOR $2;
  pJournalNumber ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pPoNumber ALIAS FOR $5;
  pDocDate ALIAS FOR $6;
  pAmount ALIAS FOR $7;
  pNotes ALIAS FOR $8;
  pAccntid ALIAS FOR $9;
  pDueDate ALIAS FOR $10;
  pTermsid ALIAS FOR $11;
  pCurrId ALIAS FOR $12;
  _vendName TEXT;
  _apAccntid INTEGER;
  _prepaidAccntid INTEGER;
  _accntid INTEGER;
  _glSequence INTEGER;
  _journalNumber INTEGER;
  _apopenid INTEGER;
  _baseAmount NUMERIC;
  _taxBaseValue NUMERIC;
  _test INTEGER;

BEGIN

  _apopenid := pId;

  SELECT findAPAccount(pVendid) INTO _apAccntid;
  SELECT findAPPrepaidAccount(pVendid) INTO _prepaidAccntid;

  SELECT vend_name INTO _vendName
  FROM vendinfo
  WHERE (vend_id=pVendid);
  
  _accntid := pAccntid;

  PERFORM accnt_id
     FROM accnt
    WHERE (accnt_id=_accntid);
  IF (FOUND) THEN
    _prepaidAccntid := _accntid;
  ELSE
    _accntid := -1;
  END IF;

  IF(pJournalNumber IS NULL) THEN
    SELECT fetchJournalNumber('AP-MISC') INTO _journalNumber;
  ELSE
    _journalNumber := pJournalNumber;
  END IF;

  SELECT fetchGLSequence() INTO _glSequence;

  IF (_apopenid IS NOT NULL) THEN
    UPDATE apopen SET
      apopen_username=getEffectiveXtUser(), apopen_journalnumber=_journalNumber,
      apopen_vend_id=pVendid, apopen_docnumber=pDocNumber,
      apopen_doctype='C', apopen_ponumber=pPoNumber,
      apopen_docdate=pDocDate, apopen_duedate=pDueDate,
      apopen_distdate=pDocDate, apopen_terms_id=pTermsid,
      apopen_amount=pAmount, apopen_paid=0,
      apopen_open=(pAmount <> 0), apopen_notes=pNotes,
      apopen_accnt_id=_accntid, apopen_curr_id=pCurrId,
      apopen_closedate=CASE WHEN (pAmount = 0) THEN pDocdate END
    WHERE apopen_id = _apopenid;
  ELSE
    SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
    INSERT INTO apopen
    ( apopen_id, apopen_username, apopen_journalnumber,
      apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
      apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
      apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_accnt_id, apopen_curr_id,
      apopen_closedate )
    VALUES
    ( _apopenid, getEffectiveXtUser(), _journalNumber,
      pVendid, pDocNumber, 'C', pPoNumber,
      pDocDate, pDueDate, pDocDate, pTermsid,
      pAmount, 0, (pAmount <> 0), pNotes, _accntid, pCurrId,
      CASE WHEN (pAmount = 0) THEN pDocDate END );
  END IF;

  _baseAmount := round(currToBase(pCurrId, pAmount, pDocDate), 2);

  -- Debit the A/P account for the full amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/P', 'CM',
                              pDocNumber, _apAccntid,
                              (_baseAmount * -1),
                              pDocDate, (_vendName || ' ' || pNotes) ) INTO _test;

  -- Credit the Tax account for the tax amount
  _taxBaseValue := addTaxToGLSeries(_glSequence,
				      'A/P', 'CM', pDocNumber,
				      pCurrId, pDocDate, pDocDate,
                                      'apopentax', _apopenid,
                                      _vendName);

  UPDATE apopentax SET taxhist_journalnumber = _journalNumber
  WHERE taxhist_parent_id=_apopenid;

  -- Credit the Prepaid account for the basis amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/P', 'CM',
                              pDocNumber, _prepaidAccntid,
                              (_baseAmount - _taxBaseValue),
                              pDocDate, (_vendName || ' ' || pNotes) ) INTO _test;

  --  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _journalNumber) INTO _test;
  IF (_test < 0) THEN
    DELETE FROM apopen WHERE (apopen_id=_apopenid);
    PERFORM deleteGLSeries(_glSequence);
    RAISE EXCEPTION 'postGLSeries commit failed with %', _test;
  END IF;

  RETURN pJournalNumber;

END;

Function: public.createapcreditmemo(integer, integer, text, text, date, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;

BEGIN
  RETURN createAPCreditMemo(pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, -1, pDocDate, -1, baseCurrId() );
END;

Function: public.createapcreditmemo(integer, integer, text, text, date, numeric, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
BEGIN
  RETURN createAPCreditMemo( pVendid, pJournalNumber,
                             pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDocDate, -1, baseCurrId() );
END;

Function: public.createapcreditmemo(integer, integer, text, text, date, numeric, text, integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
  pDueDate ALIAS FOR $9;
  pTermsid ALIAS FOR $10;
BEGIN
  RETURN createAPCreditMemo( pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, baseCurrId() );
END;

Function: public.createapcreditmemo(integer, integer, text, text, date, numeric, text, integer, date, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
  pDueDate ALIAS FOR $9;
  pTermsid ALIAS FOR $10;
  pCurrId ALIAS FOR $11;
BEGIN
  RETURN createAPCreditMemo( NULL, pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, pCurrId );
END;

Function: public.createapcreditmemo(integer, text, text, date, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  _result INTEGER;

BEGIN

  SELECT createAPCreditMemo( pVendid, fetchJournalNumber('AP-MISC'),
                             pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, -1, pDocDate, -1, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapcreditmemo(integer, text, text, date, numeric, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  pAccntid ALIAS FOR $7;
  _result INTEGER;

BEGIN

  SELECT createAPCreditMemo( pVendid, fetchJournalNumber('AP-MISC'),
                             pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDocDate, -1, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapcreditmemo(integer, text, text, date, numeric, text, integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  pAccntid ALIAS FOR $7;
  pDueDate ALIAS FOR $8;
  pTermsid ALIAS FOR $9;
  _result INTEGER;

BEGIN

  SELECT createAPCreditMemo( pVendid, fetchJournalNumber('AP-MISC'),
                             pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapcreditmemoapplication(integer, integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceApopenId	ALIAS FOR $1;
  pTargetApopenId	ALIAS FOR $2;
  pAmount		ALIAS FOR $3;
  pCurrId		ALIAS FOR $4;
  _apCreditApplyId	INTEGER;

BEGIN
  IF (pAmount > (SELECT ROUND(apopen_amount - apopen_paid, 2)
		  FROM apopen
		 WHERE (apopen_id=pTargetApopenId))) THEN
    RETURN -1;
  END IF;

  IF (pAmount > (SELECT ROUND((apopen_amount - apopen_paid) - 
		       COALESCE(SUM(currToCurr(apcreditapply_curr_id,
						apopen_curr_id, 
						apcreditapply_amount, 
						apopen_docdate)), 0), 2)
             FROM apopen LEFT OUTER JOIN apcreditapply 
               ON ((apcreditapply_source_apopen_id=apopen_id) 
              AND (apcreditapply_target_apopen_id<>pTargetApopenId)) 
             WHERE (apopen_id=pSourceApopenId) 
             GROUP BY apopen_amount, apopen_paid)) THEN
      RETURN -2;
    END IF;

  SELECT apcreditapply_id INTO _apCreditApplyId
    FROM apcreditapply
   WHERE ((apcreditapply_source_apopen_id=pSourceApopenId)
     AND  (apcreditapply_target_apopen_id=pTargetApopenId));

  IF (FOUND) THEN
    UPDATE apcreditapply SET apcreditapply_amount=pAmount,
			     apcreditapply_curr_id=pCurrId
    WHERE (apcreditapply_id=_apCreditApplyId);
  ELSE
    _apCreditApplyId := NEXTVAL('apcreditapply_apcreditapply_id_seq');
    INSERT INTO apcreditapply (
      apcreditapply_id, apcreditapply_source_apopen_id,
      apcreditapply_target_apopen_id,
      apcreditapply_amount, apcreditapply_curr_id
    ) VALUES (
      _apCreditApplyId, pSourceApopenId,
      pTargetApopenId,
      pAmount, pCurrId);
  END IF;

  RETURN _apCreditApplyId;

END;

Function: public.createapdebitmemo(integer, integer, integer, text, text, date, numeric, text, integer, date, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pId ALIAS FOR $1;
  pVendid ALIAS FOR $2;
  pJournalNumber ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pPoNumber ALIAS FOR $5;
  pDocDate ALIAS FOR $6;
  pAmount ALIAS FOR $7;
  pNotes ALIAS FOR $8;
  pAccntid ALIAS FOR $9;
  pDueDate ALIAS FOR $10;
  pTermsid ALIAS FOR $11;
  pCurrId ALIAS FOR $12;
  _vendName TEXT;
  _apAccntid INTEGER;
  _prepaidAccntid INTEGER;
  _accntid INTEGER;
  _glSequence INTEGER;
  _journalNumber INTEGER;
  _apopenid INTEGER;
  _baseAmount NUMERIC;
  _taxBaseValue NUMERIC;
  _test INTEGER;

BEGIN

  _apopenid := pId;

  SELECT findAPAccount(pVendid) INTO _apAccntid;
  SELECT findAPPrepaidAccount(pVendid) INTO _prepaidAccntid;

  SELECT vend_name INTO _vendName
  FROM vendinfo
  WHERE (vend_id=pVendid);

  _accntid := pAccntid;

  PERFORM accnt_id
     FROM accnt
    WHERE (accnt_id=_accntid);
  IF (FOUND) THEN
    _prepaidAccntid := _accntid;
  ELSE
    _accntid := -1;
  END IF;

  IF(pJournalNumber IS NULL) THEN
    SELECT fetchJournalNumber('AP-MISC') INTO _journalNumber;
  ELSE
    _journalNumber := pJournalNumber;
  END IF;

  SELECT fetchGLSequence() INTO _glSequence;

  IF (_apopenid IS NOT NULL) THEN
    UPDATE apopen SET
      apopen_username=getEffectiveXtUser(), apopen_journalnumber=_journalNumber,
      apopen_vend_id=pVendid, apopen_docnumber=pDocNumber,
      apopen_doctype='D', apopen_ponumber=pPoNumber,
      apopen_docdate=pDocDate, apopen_duedate=pDueDate,
      apopen_distdate=pDocDate, apopen_terms_id=pTermsid,
      apopen_amount=pAmount, apopen_paid=0,
      apopen_open=(pAmount <> 0), apopen_notes=pNotes,
      apopen_accnt_id=_accntid, apopen_curr_id=pCurrId,
      apopen_closedate=CASE WHEN (pAmount = 0) THEN pDocdate END
    WHERE apopen_id = _apopenid;
  ELSE
    SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
    INSERT INTO apopen
    ( apopen_id, apopen_username, apopen_journalnumber,
      apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
      apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
      apopen_amount, apopen_paid, apopen_discountable_amount, apopen_open, apopen_notes, apopen_accnt_id, apopen_curr_id,
      apopen_closedate )
    VALUES
    ( _apopenid, getEffectiveXtUser(), _journalNumber,
      pVendid, pDocNumber, 'D', pPoNumber,
      pDocDate, pDueDate, pDocDate, pTermsid,
      pAmount, 0, 0, (pAmount <> 0), pNotes, _accntid, pCurrId,
      CASE WHEN (pAmount = 0) THEN pDocDate END );
  END IF;

  _baseAmount := round(currToBase(pCurrId, pAmount, pDocDate), 2);

  -- Credit the A/P account for the full amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/P', 'DM',
                              pDocNumber, _apAccntid,
                              _baseAmount,
                              pDocDate, (_vendName || ' ' || pNotes) ) INTO _test;

  -- Debit the Tax account for the tax amount
  _taxBaseValue := addTaxToGLSeries(_glSequence,
				      'A/P', 'DM', pDocNumber,
				      pCurrId, pDocDate, pDocDate,
                                      'apopentax', _apopenid,
                                      _vendName);

  UPDATE apopentax SET taxhist_journalnumber = _journalNumber
  WHERE taxhist_parent_id=_apopenid;

  -- Debit the Prepaid account for the basis amount
  -- Note, the taxBaseValue is negative so it is added
  SELECT insertIntoGLSeries ( _glSequence, 'A/P', 'DM',
                              pDocNumber, _prepaidAccntid,
                              (_baseAmount + _taxBaseValue) * -1,
                              pDocDate, (_vendName || ' ' || pNotes) ) INTO _test;

  --  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _journalNumber) INTO _test;
  IF (_test < 0) THEN
    DELETE FROM apopen WHERE (apopen_id=_apopenid);
    PERFORM deleteGLSeries(_glSequence);
    RAISE EXCEPTION 'postGLSeries commit failed with %', _test;
  END IF;

  RETURN _apopenid;

END;

Function: public.createapdebitmemo(integer, integer, text, text, date, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;

BEGIN

  RETURN createAPDebitMemo(pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, -1, pDocDate, -1, baseCurrId() );

END;

Function: public.createapdebitmemo(integer, integer, text, text, date, numeric, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
BEGIN
  RETURN createAPDebitMemo( pVendid, pJournalNumber,
                            pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDocDate, -1, baseCurrId() );
END;

Function: public.createapdebitmemo(integer, integer, text, text, date, numeric, text, integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
  pDueDate ALIAS FOR $9;
  pTermsid ALIAS FOR $10;

BEGIN
  RETURN createAPDebitMemo(pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, baseCurrId() );
END;

Function: public.createapdebitmemo(integer, integer, text, text, date, numeric, text, integer, date, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pPoNumber ALIAS FOR $4;
  pDocDate ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pNotes ALIAS FOR $7;
  pAccntid ALIAS FOR $8;
  pDueDate ALIAS FOR $9;
  pTermsid ALIAS FOR $10;
  pCurrId ALIAS FOR $11;

BEGIN
  RETURN createAPDebitMemo(NULL, pVendid, pJournalNumber, pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, pCurrId );
END;

Function: public.createapdebitmemo(integer, text, text, date, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  _result INTEGER;

BEGIN

  SELECT createAPDebitMemo( pVendid, fetchJournalNumber('AP-MISC'),
                            pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, -1, pDocDate, -1, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapdebitmemo(integer, text, text, date, numeric, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  pAccntid ALIAS FOR $7;
  _result INTEGER;

BEGIN

  SELECT createAPDebitMemo( pVendid, fetchJournalNumber('AP-MISC'),
                            pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDocDate, -1, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapdebitmemo(integer, text, text, date, numeric, text, integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pPoNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  pAccntid ALIAS FOR $7;
  pDueDate ALIAS FOR $8;
  pTermsid ALIAS FOR $9;
  _result INTEGER;

BEGIN

  SELECT createAPDebitMemo( pVendid, fetchJournalNumber('AP-MISC'),
                            pDocNumber, pPoNumber, pDocDate, pAmount, pNotes, pAccntid, pDueDate, pTermsid, baseCurrId() ) INTO _result;

  RETURN _result;

END;

Function: public.createapdiscount(integer, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pAmount ALIAS FOR $3;
  _ap RECORD;
  _sequence INTEGER;
  _apopenid INTEGER;
  _apcreditapplyid INTEGER;
  _result INTEGER;
  _crAccnt INTEGER;
  _dbAccnt INTEGER;
  _reference    TEXT;
  _discountDateAmt NUMERIC;

BEGIN

  SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;

  SELECT * INTO _ap
  FROM apopen
  WHERE (apopen_id = pApopenid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  _crAccnt := findAPDiscountAccount(_ap.apopen_vend_id);
  _dbAccnt := findAPAccount(_ap.apopen_vend_id);
  _reference := ('Discount for ' || _ap.apopen_doctype || ' ' || _ap.apopen_docnumber);

  SELECT fetchGLSequence() INTO _sequence;

  _discountDateAmt = round(pAmount / _ap.apopen_curr_rate, 2);
  PERFORM insertIntoGLSeries( _sequence, 'A/P', 'DS', _ap.apopen_docnumber,
                              _dbAccnt,
                              _discountDateAmt * -1,
                              CURRENT_DATE,
                              _reference);
  PERFORM insertIntoGLSeries( _sequence, 'A/P', 'DS', _ap.apopen_docnumber,
                              _crAccnt,
                              _discountDateAmt,
                              CURRENT_DATE,
                              _reference);

  PERFORM postGLSeries(_sequence, pJournalNumber);

  INSERT INTO apopen
  ( apopen_id, apopen_username, apopen_journalnumber,
    apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
    apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id, apopen_curr_id,
    apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_discount, apopen_curr_rate )
  SELECT _apopenid, getEffectiveXtUser(), pJournalNumber,
         apopen_vend_id, apopen_docnumber, 'C', apopen_ponumber,
         CURRENT_DATE, CURRENT_DATE, CURRENT_DATE, -1, apopen_curr_id,
         pAmount, 0, TRUE, _reference, TRUE, apopen_curr_rate
    FROM apopen
   WHERE (apopen_id=pApopenid);

  SELECT apcreditapply_id INTO _apcreditapplyid
    FROM apcreditapply
   WHERE ( (apcreditapply_source_apopen_id=_apopenid)
     AND   (apcreditapply_target_apopen_id=pApopenid) );
  IF (FOUND) THEN
    UPDATE apcreditapply
       SET apcreditapply_amount=pAmount
     WHERE (apcreditapply_id=_apcreditapplyid);
  ELSE
    SELECT nextval('apcreditapply_apcreditapply_id_seq') INTO _apcreditapplyid;
    INSERT INTO apcreditapply
           ( apcreditapply_id, apcreditapply_source_apopen_id,
             apcreditapply_target_apopen_id, apcreditapply_amount,
             apcreditapply_curr_id )
    VALUES ( _apcreditapplyid, _apopenid, pApopenid, pAmount, _ap.apopen_curr_id );
  END IF;

  SELECT postAPCreditMemoApplication(_apopenid) INTO _result;

  IF (_result < 0) THEN
    RETURN _result;
  END IF;

  RETURN pJournalNumber;

END;

Function: public.createapdiscount(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  pAmount ALIAS FOR $2;
  _result INTEGER;
  
BEGIN

  SELECT createAPDiscount(pApopenid, fetchJournalNumber('AP-MISC'), pAmount) INTO _result;

  RETURN _result;

END;

Function: public.createarcashdeposit(integer, text, text, date, numeric, text, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pDocNumber ALIAS FOR $2;
  pOrderNumber ALIAS FOR $3;
  pDocDate ALIAS FOR $4;
  pAmount ALIAS FOR $5;
  pNotes ALIAS FOR $6;
  pJournalNumber ALIAS FOR $7;
  pCurrId ALIAS FOR $8;
  _glSequence INTEGER;
  _aropenid INTEGER;

BEGIN

  IF (pAmount <= 0) THEN
    RETURN 0;
  END IF;

  SELECT NEXTVAL('aropen_aropen_id_seq') INTO _aropenid;

  SELECT insertGLTransaction( pJournalNumber, 'A/R', 'CD',
                              pDocNumber, pNotes, cr.accnt_id, db.accnt_id,
                              _aropenid,
                              round(currToBase(pCurrId, pAmount, pDocDate), 2),
                              pDocDate) INTO _glSequence
  FROM accnt AS db, accnt AS cr
  WHERE ( (db.accnt_id = findPrepaidAccount(pCustid))
   AND (cr.accnt_id = findDeferredAccount(pCustid)) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'There was an error creating the Customer Deposit GL Transactions. No Deferred Revenue Account is assigned.';
  END IF;

  INSERT INTO aropen
  ( aropen_id, aropen_username, aropen_journalnumber,
    aropen_cust_id, aropen_docnumber, aropen_doctype, aropen_ordernumber,
    aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id, aropen_salesrep_id,
    aropen_amount, aropen_paid, aropen_commission_due, aropen_commission_paid,
    aropen_applyto, aropen_ponumber, aropen_cobmisc_id,
    aropen_open, aropen_notes, aropen_rsncode_id,
    aropen_salescat_id, aropen_accnt_id, aropen_curr_id )
  VALUES
  ( _aropenid, getEffectiveXtUser(), pJournalNumber,
    pCustid, pDocNumber, 'R', pOrderNumber,
    pDocDate, pDocDate, pDocDate, -1, NULL,
    round(pAmount, 2), 0, 0.0, FALSE,
    '', '', -1,
    TRUE, pNotes, -1,
    -1, -1, pCurrId );

  RETURN _aropenid;

END;

Function: public.createarcreditmemo(pcoccpayid integer, paraccntid integer, pcurrid text, pjournalnumber text, pcommissiondue date, psalesrepid numeric, ptermsid text, pduedate integer, paccntid integer, psalescatid integer, prsncodeid date, pnotes integer, pamount integer, pdocdate numeric, pordernumber integer, pdocnumber integer, pcustid integer, pid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _accntid        INTEGER;
  _arAccntid      INTEGER;
  _aropenid       INTEGER;
  _cohistid       INTEGER;
  _custName       TEXT;
  _duedate        DATE    := COALESCE(pDueDate, pDocDate);
  _glSequence     INTEGER;
  _journalNumber  INTEGER;
  _prepaidAccntid INTEGER;
  _salescatid     INTEGER;
  _taxBaseValue   NUMERIC;
  _test           INTEGER;
  _tmp            INTEGER;

BEGIN

  _aropenid := pId;

  IF (pAmount <= 0) THEN
    RETURN 0;
  END IF;

  _arAccntid := COALESCE(pARAccntid, findARAccount(pCustid));
  _prepaidAccntid := findPrepaidAccount(pCustid);

  _accntid := pAccntid;
  _salescatid := pSalescatid;

  SELECT cust_name INTO _custName
  FROM custinfo
  WHERE (cust_id=pCustid);

  IF EXISTS(SELECT 1 FROM accnt WHERE (accnt_id=_accntid)) THEN
    _prepaidAccntid := _accntid;
  ELSE
    _accntid := -1;
  END IF;

  SELECT accnt_id INTO _tmp
    FROM salescat, accnt
   WHERE ((salescat_prepaid_accnt_id=accnt_id)
     AND  (salescat_id=_salescatid));
  IF (FOUND) THEN
    _accntid := -1;
    _prepaidAccntid := _tmp;
  ELSE
    _salescatid = -1;
  END IF;

  IF(pJournalNumber IS NULL) THEN
    SELECT fetchJournalNumber('AR-MISC') INTO _journalNumber;
  ELSE
    _journalNumber := pJournalNumber;
  END IF;

  _glSequence := fetchGLSequence();

  -- CreatelUpdate aropen for full amount
  IF (_aropenid IS NOT NULL) THEN
    UPDATE aropen SET
      aropen_username=getEffectiveXtUser(), aropen_journalnumber=_journalNumber,
      aropen_cust_id=pCustid, aropen_docnumber=pDocNumber, aropen_doctype='C',
      aropen_ordernumber=pOrderNumber,aropen_docdate=pDocDate, aropen_duedate=_duedate,
      aropen_distdate=pDocDate, aropen_terms_id=pTermsid,
      aropen_salesrep_id=pSalesrepid, aropen_amount=round(pAmount, 2), aropen_paid=0,
      aropen_commission_due=pCommissiondue, aropen_commission_paid=FALSE,
      aropen_applyto='', aropen_ponumber='', aropen_cobmisc_id=-1,
      aropen_open=TRUE, aropen_notes=pNotes, aropen_rsncode_id=pRsncodeid,
      aropen_salescat_id=_salescatid, aropen_accnt_id=_accntid, aropen_curr_id=pCurrId
    WHERE aropen_id = pId;
  ELSE
    SELECT NEXTVAL('aropen_aropen_id_seq') INTO _aropenid;
    INSERT INTO aropen
    ( aropen_id, aropen_username, aropen_journalnumber,
      aropen_cust_id, aropen_docnumber, aropen_doctype, aropen_ordernumber,
      aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id, aropen_salesrep_id,
      aropen_amount, aropen_paid, aropen_commission_due, aropen_commission_paid,
      aropen_applyto, aropen_ponumber, aropen_cobmisc_id,
      aropen_open, aropen_notes, aropen_rsncode_id,
      aropen_salescat_id, aropen_accnt_id, aropen_curr_id )
    VALUES
    ( _aropenid, getEffectiveXtUser(), _journalNumber,
      pCustid, pDocNumber, 'C', pOrderNumber,
      pDocDate, _duedate, pDocDate, pTermsid, pSalesrepid,
      round(pAmount, 2), 0, pCommissiondue, FALSE,
      '', '', -1,
      TRUE, pNotes, pRsncodeid,
      _salescatid, _accntid, pCurrId );
  END IF;

  -- Credit the A/R account for the full amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/R', 'CM',
                              pDocNumber, _arAccntid,
                              round(currToBase(pCurrId, pAmount, pDocDate), 2),
                              pDocDate, (_custName || ' ' || pNotes)) INTO _test;

  -- Debit the Tax account for the tax amount
  _taxBaseValue := addTaxToGLSeries(_glSequence,
				      'A/R', 'CM', pDocNumber,
				      pCurrId, pDocDate, pDocDate,
                                      'aropentax', _aropenid,
                                      (_custName || ' ' || pNotes));

  UPDATE aropentax SET taxhist_journalnumber = _journalNumber
  WHERE taxhist_parent_id=_aropenid;

  -- Debit the Prepaid account for the basis amount
  -- Note, _taxBaseValue is negative so it is added to pAmount
  SELECT insertIntoGLSeries ( _glSequence, 'A/R', 'CM',
                              pDocNumber, _prepaidAccntid,
                              round(currToBase(pCurrId, pAmount * -1, pDocDate) + _taxBaseValue * -1, 2),
                              pDocDate, (_custName || ' ' || pNotes)) INTO _test;

  --  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _journalNumber) INTO _test;
  IF (_test < 0) THEN
    DELETE FROM aropen WHERE (aropen_id=_aropenid);
    PERFORM deleteGLSeries(_glSequence);
    RAISE EXCEPTION 'postGLSeries commit failed with %', _test;
  END IF;

  --  Record Sales History
  INSERT INTO cohist
  ( cohist_cust_id,
   cohist_itemsite_id, cohist_shipto_id,
    cohist_misc_type, cohist_misc_descrip,
    cohist_shipdate, cohist_shipvia,
    cohist_ordernumber, cohist_ponumber, cohist_orderdate,
    cohist_doctype, cohist_invcnumber, cohist_invcdate,
    cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
    cohist_salesrep_id,
    cohist_commission, cohist_commissionpaid,
    cohist_curr_id, cohist_sequence, cohist_cohead_ccpay_id)
  VALUES
  (CASE WHEN pCustid < 0 THEN NULL ELSE pCustid END,
   -1, -1,
    'M', 'A/R Misc Credit Memo',
    pDocDate, '',
    pOrderNumber, '', pDocDate,
    'C', pDocNumber, pDocDate,
    1, (pAmount - _taxBaseValue) * -1, 0,
    CASE WHEN pSalesrepid < 0 THEN NULL ELSE pSalesrepid END,
    (pCommissiondue * -1.0), FALSE,
    pCurrId, _glSequence, pCoCcpayId)
  RETURNING cohist_id INTO _cohistid;

  INSERT INTO cohisttax
  ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
    taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
    taxhist_percent, taxhist_amount, taxhist_tax,
    taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
    taxhist_journalnumber )
  SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
         taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
         taxhist_percent, taxhist_amount, taxhist_tax,
         taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
         taxhist_journalnumber
  FROM aropentax
  WHERE (taxhist_parent_id=_aropenid);

  RETURN _aropenid;

END;

Function: public.createardebitmemo(integer, integer, integer, text, text, date, numeric, text, integer, integer, integer, date, integer, integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pId			ALIAS FOR $1;
  pCustid		ALIAS FOR $2;
  pJournalNumber	ALIAS FOR $3;
  pDocNumber		ALIAS FOR $4;
  pOrderNumber		ALIAS FOR $5;
  pDocDate		ALIAS FOR $6;
  pAmount		ALIAS FOR $7;
  pNotes		ALIAS FOR $8;
  pRsncodeid		ALIAS FOR $9;
  pSalescatid		ALIAS FOR $10;
  pAccntid		ALIAS FOR $11;
  pDueDate		ALIAS FOR $12;
  pTermsid		ALIAS FOR $13;
  pSalesrepid		ALIAS FOR $14;
  pCommissiondue	ALIAS FOR $15;
  pCurrId		ALIAS FOR $16;
  _custName TEXT;
  _journalNumber INTEGER;
  _arAccntid INTEGER;
  _prepaidAccntid INTEGER;
  _salescatid INTEGER;
  _accntid INTEGER;
  _glSequence INTEGER;
  _aropenid INTEGER;
  _cohistid INTEGER;
  _tmp INTEGER;
  _test INTEGER;
  _taxBaseValue NUMERIC;

BEGIN
  _aropenid=pId;
  
  IF (pAmount <= 0) THEN
    RETURN 0;
  END IF;

  SELECT findARAccount(pCustid) INTO _arAccntid;
  SELECT findPrepaidAccount(pCustid) INTO _prepaidAccntid;

  _accntid := pAccntid;
  _salescatid := pSalescatid;

  SELECT cust_name INTO _custName
  FROM custinfo
  WHERE (cust_id=pCustid);
  
  PERFORM accnt_id
     FROM accnt
    WHERE (accnt_id=_accntid);
  IF (FOUND) THEN
    _prepaidAccntid := _accntid;
  ELSE
    _accntid := -1;
  END IF;

  SELECT accnt_id INTO _tmp
    FROM salescat, accnt
   WHERE ((salescat_prepaid_accnt_id=accnt_id)
     AND  (salescat_id=_salescatid));
  IF (FOUND) THEN
    _accntid := -1;
    _prepaidAccntid := _tmp;
  ELSE
    _salescatid = -1;
  END IF;

  IF (pJournalNumber IS NULL) THEN
    _journalNumber := fetchJournalNumber('AR-MISC');
  ELSE
    _journalNumber := pJournalNumber;
  END IF;

  SELECT fetchGLSequence() INTO _glSequence;

  -- CreatelUpdate aropen for full amount
  IF (_aropenid IS NOT NULL) THEN
    UPDATE aropen SET
      aropen_username=getEffectiveXtUser(), aropen_journalnumber=_journalNumber,
      aropen_cust_id=pCustid, aropen_docnumber=pDocNumber, aropen_doctype='D', 
      aropen_ordernumber=pOrderNumber,aropen_docdate=pDocDate, aropen_duedate=pDueDate, 
      aropen_distdate=pDocDate, aropen_terms_id=pTermsid, 
      aropen_salesrep_id=pSalesrepid, aropen_amount=round(pAmount, 2), aropen_paid=0, 
      aropen_commission_due=pCommissiondue, aropen_commission_paid=FALSE,
      aropen_applyto='', aropen_ponumber='', aropen_cobmisc_id=-1,
      aropen_open=TRUE, aropen_notes=pNotes, aropen_rsncode_id=pRsncodeid,
      aropen_salescat_id=_salescatid, aropen_accnt_id=_accntid, aropen_curr_id=pCurrId
    WHERE aropen_id = pId;
  ELSE
    SELECT NEXTVAL('aropen_aropen_id_seq') INTO _aropenid;
    INSERT INTO aropen
    ( aropen_id, aropen_username, aropen_journalnumber,
      aropen_cust_id, aropen_docnumber, aropen_doctype, aropen_ordernumber,
      aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id, aropen_salesrep_id,
      aropen_amount, aropen_paid, aropen_commission_due, aropen_commission_paid,
      aropen_applyto, aropen_ponumber, aropen_cobmisc_id,
      aropen_open, aropen_notes, aropen_rsncode_id,
      aropen_salescat_id, aropen_accnt_id, aropen_curr_id )
    VALUES
    ( _aropenid, getEffectiveXtUser(), _journalNumber,
      pCustid, pDocNumber, 'D', pOrderNumber,
      pDocDate, pDueDate, pDocDate, pTermsid, pSalesrepid,
      round(pAmount, 2), 0, pCommissiondue, FALSE,
      '', '', -1,
      TRUE, pNotes, pRsncodeid,
      _salescatid, _accntid, pCurrId );
  END IF;

  -- Debit the A/R account for the full amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/R', 'DM',
                              pDocNumber, _arAccntid,
                              round(currToBase(pCurrId, pAmount, pDocDate) * -1, 2),
                              pDocDate, (_custName || ' ' || pNotes)) INTO _test;

  -- Credit the Tax account for the tax amount
  _taxBaseValue := addTaxToGLSeries(_glSequence,
				      'A/R', 'DM', pDocNumber,
				      pCurrId, pDocDate, pDocDate,
                                      'aropentax', _aropenid,
                                      (_custName || ' ' || pNotes));

  UPDATE aropentax SET taxhist_journalnumber = _journalNumber
  WHERE taxhist_parent_id=_aropenid;

  -- Credit the Prepaid account for the basis amount
  SELECT insertIntoGLSeries ( _glSequence, 'A/R', 'DM',
                              pDocNumber, _prepaidAccntid,
                              round(currToBase(pCurrId, (pAmount), pDocDate), 2) - _taxBaseValue,
                              pDocDate, (_custName || ' ' || pNotes)) INTO _test;

  --  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _journalNumber) INTO _test;
  IF (_test < 0) THEN
    DELETE FROM aropen WHERE (aropen_id=_aropenid);
    PERFORM deleteGLSeries(_glSequence);
    RAISE EXCEPTION 'postGLSeries commit failed with %', _test;
  END IF;

  --  Record Sales History
  SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
  INSERT INTO cohist
  ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
    cohist_misc_type, cohist_misc_descrip,
    cohist_shipdate, cohist_shipvia,
    cohist_ordernumber, cohist_ponumber, cohist_orderdate,
    cohist_doctype, cohist_invcnumber, cohist_invcdate,
    cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
    cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
    cohist_curr_id, cohist_sequence )
  VALUES
  ( _cohistid, pCustid, -1, -1,
    'M', 'A/R Misc Debit Memo',
    pDocDate, '',
    '', '', pDocDate,
    'D', pDocNumber, pDocDate,
    1, (pAmount - _taxBaseValue), 0,
    pSalesrepid, pCommissiondue, FALSE,
    pCurrId, _glSequence );
  INSERT INTO cohisttax
  ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
    taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
    taxhist_percent, taxhist_amount, taxhist_tax,
    taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
    taxhist_journalnumber )
  SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
         taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
         taxhist_percent, taxhist_amount, taxhist_tax,
         taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
         taxhist_journalnumber
  FROM aropentax
  WHERE (taxhist_parent_id=_aropenid);

  RETURN _aropenid;

END;

Function: public.createbillingheader(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid		ALIAS FOR $1;
  _cobmiscid		INTEGER;
  _cohead		cohead%ROWTYPE;
  _miscApplied          NUMERIC := 0.0;
  _freight		NUMERIC;
  _freighttypeid        INTEGER;
  _invcDate		DATE;
  _schedDate		DATE;
  _shipDate		DATE;
  _shipVia		TEXT;
  _tax			NUMERIC;

BEGIN

  --  Fetch cohead
  SELECT * INTO _cohead
  FROM cohead
  WHERE (cohead_id=pSoheadid);

  --  Check for an existing cobmisc
  SELECT cobmisc_id INTO _cobmiscid
  FROM cobmisc
  WHERE ( (NOT cobmisc_posted)
   AND (cobmisc_cohead_id=pSoheadid) );

  IF (FOUND) THEN
  --  Find a Shipping-Entered freight charge
    SELECT SUM(currToCurr(shiphead_freight_curr_id, _cohead.cohead_curr_id,
                          shiphead_freight, CURRENT_DATE)) INTO _freight
    FROM (
    SELECT shiphead_id, shiphead_freight_curr_id, shiphead_freight
    FROM shiphead JOIN shipitem ON (shipitem_shiphead_id=shiphead_id AND NOT shipitem_invoiced)
    WHERE ((shiphead_order_type='SO')
      AND  (shiphead_order_id=pSoheadid))
    GROUP BY shiphead_id, shiphead_freight_curr_id, shiphead_freight) AS data;

    IF (_freight IS NOT NULL) THEN
      UPDATE cobmisc SET cobmisc_freight = _freight
      WHERE (cobmisc_id=_cobmiscid);
    END IF;

    RETURN _cobmiscid;
  END IF;

  --  Find misc charges that have already been applied for the S/O
  SELECT COALESCE(SUM(cobmisc_misc), 0.0) INTO _miscApplied
  FROM cobmisc
  WHERE (cobmisc_cohead_id=pSoheadid);

  SELECT NEXTVAL('cobmisc_cobmisc_id_seq') INTO _cobmiscid;

  --  Check for a valid shipdate
  SELECT MIN(shiphead_shipdate) INTO _shipDate
  FROM shiphead, shipitem
  WHERE ( (shipitem_shiphead_id=shiphead_id)
   AND (NOT shipitem_invoiced)
   AND (shiphead_shipped)
   AND (shiphead_order_type='SO')
   AND (shiphead_order_id=pSoheadid) );

  --  Schema shouldn't allow, but we'll try for now
  IF (_shipDate IS NULL) THEN
    SELECT MAX(shipitem_shipdate) INTO _shipDate
    FROM shipitem, shiphead
    WHERE ( (shipitem_shiphead_id=shiphead_id)
     AND (shiphead_order_type='SO')
     AND (shiphead_order_id=pSoheadid) );

    --  How about a transaction date
    IF (_shipDate IS NULL) THEN
      SELECT COALESCE(MAX(shipitem_transdate), CURRENT_DATE) INTO _shipDate
      FROM shipitem, shiphead
      WHERE ((shipitem_shiphead_id=shiphead_id)
        AND  (shiphead_order_type='SO')
        AND  (shiphead_order_id=pSoheadid) );
    END IF;
  END IF;

  --  Get the earliest schedule date for this order.
  SELECT MIN(coitem_scheddate) INTO _schedDate
    FROM coitem
   WHERE ((coitem_status <> 'X') AND (coitem_cohead_id=pSoheadid));

  IF (_schedDate IS NULL) THEN
    _schedDate := _shipDate;
  END IF;

  --  Find a Shipping-Entered freight charge
  SELECT SUM(currToCurr(shiphead_freight_curr_id, _cohead.cohead_curr_id,
                        shiphead_freight, CURRENT_DATE)), shiphead_shipvia
         INTO _freight, _shipVia
  FROM (
  SELECT shiphead_id, shiphead_freight_curr_id, shiphead_freight, shiphead_shipvia
  FROM shiphead JOIN shipitem ON (shipitem_shiphead_id=shiphead_id AND NOT shipitem_invoiced)
  WHERE ((shiphead_order_type='SO')
    AND  (shiphead_order_id=pSoheadid))
  GROUP BY shiphead_id, shiphead_freight_curr_id, shiphead_freight, shiphead_shipvia) AS data
  GROUP BY shiphead_shipvia;

  --  Nope, use the cohead freight charge
  IF (_freight IS NULL) THEN
    _freight	   := _cohead.cohead_freight;
  END IF;

  --  Finally, look for a Shipping-Entered Ship Via
  SELECT shiphead_shipvia INTO _shipVia
  FROM shiphead, shipitem
  WHERE ( (shipitem_shiphead_id=shiphead_id)
   AND (NOT shipitem_invoiced)
   AND (shiphead_order_type='SO')
   AND (shiphead_order_id=pSoheadid) )
  LIMIT 1;
  IF (NOT FOUND) THEN
    _shipVia := _cohead.cohead_shipvia;
  END IF;

  --Determine any tax

  SELECT 
  getFreightTaxTypeId() INTO _freighttypeid;
  SELECT SUM(COALESCE(taxdetail_tax, 0.00)) INTO _tax
  FROM calculatetaxdetail(_cohead.cohead_taxzone_id, _freighttypeid, _cohead.cohead_orderdate,_cohead.cohead_curr_id, _freight);

  --  Determine if we are using the _shipDate or _schedDate or current_date for the _invcDate
  IF( fetchMetricText('InvoiceDateSource')='scheddate') THEN
    _invcDate := _schedDate;
  ELSIF( fetchMetricText('InvoiceDateSource')='shipdate') THEN
    _invcDate := _shipDate;
  ELSE
    _invcDate := current_date;
  END IF;

   INSERT INTO cobmisc (
	cobmisc_id, cobmisc_cohead_id, cobmisc_shipvia, cobmisc_freight, cobmisc_misc, cobmisc_payment 
	,cobmisc_notes,cobmisc_shipdate ,cobmisc_invcdate,cobmisc_posted ,cobmisc_misc_accnt_id 
	,cobmisc_misc_descrip,cobmisc_closeorder,cobmisc_curr_id
	,cobmisc_taxtype_id,cobmisc_taxzone_id
	)
	SELECT
	_cobmiscid,_cohead.cohead_id,_shipVia,_freight,
        CASE WHEN (_cohead.cohead_misc - _miscApplied = 0.0) THEN 0.0
             ELSE (_cohead.cohead_misc - _miscApplied) END,0,
        _cohead.cohead_ordercomments,_shipDate,_invcDate,FALSE,_cohead.cohead_misc_accnt_id,
        _cohead.cohead_misc_descrip,NOT(cust_backorder),_cohead.cohead_curr_id,
	_cohead.cohead_taxtype_id,_cohead.cohead_taxzone_id
	FROM custinfo
	WHERE (cust_id=_cohead.cohead_cust_id);

  RETURN _cobmiscid;

END;

Function: public.createbomitem(integer, integer, integer, bpchar, integer, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text, text, text)

Returns: integer

Language: PLPGSQL

DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pIssueMethod ALIAS FOR $4;
  pUomId ALIAS FOR $5;
  pQtyPer ALIAS FOR $6;
  pScrap ALIAS FOR $7;
  pEffective ALIAS FOR $8;
  pExpires ALIAS FOR $9;
  pCreateWo ALIAS FOR $10;
  pBOOItemseqid ALIAS FOR $11;
  pSchedAtWooper ALIAS FOR $12;
  pECN ALIAS FOR $13;
  pSubType ALIAS FOR $14;
  pRevisionid ALIAS FOR $15;
  pCharId ALIAS FOR $16;
  pCharVal ALIAS FOR $17;
  pNotes ALIAS FOR $18;
  pRef ALIAS FOR $19;
  _seqNumber INTEGER;
  _bomitemid INTEGER;

BEGIN

--  Grab the next Sequence Number, if any
  SELECT MAX(bomitem_seqnumber) INTO _seqNumber
  FROM bomitem(pParentItemid,pRevisionid);

  IF (_seqNumber IS NOT NULL) THEN
   _seqNumber := (_seqNumber + 10);
  ELSE
   _seqNumber := 10;
  END IF;

  SELECT createBOMItem( pBomitemid, pParentItemid, pComponentItemid,
                        _seqNumber, pIssueMethod,
                        pUomId, pQtyPer, pScrap,
                        pEffective, pExpires,
                        pCreateWo, pBOOItemseqid, pSchedAtWooper, pECN, pSubType, pRevisionid, pCharId, pCharVal, pNotes, pRef ) INTO _bomitemid;

  RETURN _bomitemid;

END;

Function: public.createbomitem(integer, integer, integer, bpchar, integer, numeric, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pIssueMethod ALIAS FOR $4;
  pUomId ALIAS FOR $5;
  pQtyFxd ALIAS FOR $6;
  pQtyPer ALIAS FOR $7;
  pScrap ALIAS FOR $8;
  pEffective ALIAS FOR $9;
  pExpires ALIAS FOR $10;
  pCreateWo ALIAS FOR $11;
  pBOOItemseqid ALIAS FOR $12;
  pSchedAtWooper ALIAS FOR $13;
  pECN ALIAS FOR $14;
  pSubType ALIAS FOR $15;
  pRevisionid ALIAS FOR $16;
  pCharId ALIAS FOR $17;
  pCharVal ALIAS FOR $18;
  pNotes ALIAS FOR $19;
  pRef ALIAS FOR $20;
  _seqNumber INTEGER;
  _bomitemid INTEGER;

BEGIN

--  Grab the next Sequence Number, if any
  SELECT MAX(bomitem_seqnumber) INTO _seqNumber
  FROM bomitem(pParentItemid,pRevisionid);

  IF (_seqNumber IS NOT NULL) THEN
   _seqNumber := (_seqNumber + 10);
  ELSE
   _seqNumber := 10;
  END IF;

  SELECT createBOMItem( pBomitemid, pParentItemid, pComponentItemid,
                        _seqNumber, pIssueMethod,
                        pUomId, pQtyFxd, pQtyPer, pScrap,
                        pEffective, pExpires,
                        pCreateWo, pBOOItemseqid, pSchedAtWooper, pECN, pSubType, pRevisionid, pCharId, pCharVal, pNotes, pRef ) INTO _bomitemid;

  RETURN _bomitemid;

END;

Function: public.createbomitem(integer, integer, integer, integer, bpchar, integer, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text)

Returns: integer

Language: PLPGSQL

DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pSeqNumber ALIAS FOR $4;
  pIssueMethod ALIAS FOR $5;
  pUomId ALIAS FOR $6;
  pQtyPer ALIAS FOR $7;
  pScrap ALIAS FOR $8;
  pEffective ALIAS FOR $9;
  pExpires ALIAS FOR $10;
  pCreateWo ALIAS FOR $11;
  pBOOItemseqid ALIAS FOR $12;
  pSchedAtWooper ALIAS FOR $13;
  pECN ALIAS FOR $14;
  pSubType ALIAS FOR $15;
  pRevisionid ALIAS FOR $16;
  pCharId ALIAS FOR $17;
  pCharVal ALIAS FOR $18;
  _bomworksetid INTEGER;
  _temp INTEGER;
  _bomitemid INTEGER;

BEGIN

  SELECT createBOMItem( pBomitemid, pParentItemid, pComponentItemid,
                        pSeqNumber, pIssueMethod,
                        pUomId, pQtyPer, pScrap,
                        pEffective, pExpires,
                        pCreateWo, pBOOItemseqid, pSchedAtWooper, pECN, pSubType, pRevisionid, pCharId, pCharVal, NULL, NULL ) INTO _bomitemid;

  RETURN _bomitemid;
  
END;

Function: public.createbomitem(integer, integer, integer, integer, bpchar, integer, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text, text, text)

Returns: integer

Language: PLPGSQL

DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pSeqNumber ALIAS FOR $4;
  pIssueMethod ALIAS FOR $5;
  pUomId ALIAS FOR $6;
  pQtyPer ALIAS FOR $7;
  pScrap ALIAS FOR $8;
  pEffective ALIAS FOR $9;
  pExpires ALIAS FOR $10;
  pCreateWo ALIAS FOR $11;
  pBOOItemseqid ALIAS FOR $12;
  pSchedAtWooper ALIAS FOR $13;
  pECN ALIAS FOR $14;
  pSubType ALIAS FOR $15;
  pRevisionid ALIAS FOR $16;
  pCharId ALIAS FOR $17;
  pCharVal ALIAS FOR $18;
  pNotes ALIAS FOR $19;
  pRef ALIAS FOR $20;
  _bomworksetid INTEGER;
  _temp INTEGER;

BEGIN

--  Make sure that the parent and component are not the same
  IF (pParentItemid = pComponentItemid) THEN
    RETURN -1;
  END IF;

--  Make sure that the parent is not used in the component at some level
  IF ( SELECT (item_type IN ('M', 'F'))
       FROM item
       WHERE (item_id=pComponentItemid) ) THEN
    SELECT indentedWhereUsed(pParentItemid) INTO _bomworksetid;
    SELECT bomwork_id INTO _temp
    FROM bomwork
    WHERE ( (bomwork_set_id=_bomworksetid)
     AND (bomwork_item_id=pComponentItemid) )
    LIMIT 1;
    IF (FOUND) THEN
      PERFORM deleteBOMWorkset(_bomworksetid);
      RETURN -2;
    END IF;
  END IF;

  PERFORM deleteBOMWorkset(_bomworksetid);

--  Create the BOM Item
  INSERT INTO bomitem
  ( bomitem_id, bomitem_parent_item_id, bomitem_item_id,
    bomitem_seqnumber, bomitem_issuemethod,
    bomitem_uom_id, bomitem_qtyper, bomitem_scrap,
    bomitem_effective, bomitem_expires,
    bomitem_createwo,
    bomitem_booitem_seq_id, bomitem_schedatwooper,
    bomitem_ecn, bomitem_subtype, bomitem_moddate, bomitem_rev_id,
    bomitem_char_id, bomitem_value, bomitem_notes, bomitem_ref )
  VALUES
  ( pBomitemid, pParentItemid, pComponentItemid,
    pSeqNumber, pIssueMethod,
    pUomId, pQtyPer, pScrap,
    pEffective, pExpires,
    pCreateWo,
    pBOOItemseqid, COALESCE(pSchedAtWooper, FALSE),
    pECN, pSubType, CURRENT_DATE, pRevisionid,
    pCharId,pCharVal,pNotes, pRef );

  RETURN pBomitemid;

END;

Function: public.createbomitem(integer, integer, integer, integer, bpchar, integer, numeric, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pSeqNumber ALIAS FOR $4;
  pIssueMethod ALIAS FOR $5;
  pUomId ALIAS FOR $6;
  pQtyFxd ALIAS FOR $7;
  pQtyPer ALIAS FOR $8;
  pScrap ALIAS FOR $9;
  pEffective ALIAS FOR $10;
  pExpires ALIAS FOR $11;
  pCreateWo ALIAS FOR $12;
  pBOOItemseqid ALIAS FOR $13;
  pSchedAtWooper ALIAS FOR $14;
  pECN ALIAS FOR $15;
  pSubType ALIAS FOR $16;
  pRevisionid ALIAS FOR $17;
  pCharId ALIAS FOR $18;
  pCharVal ALIAS FOR $19;
  _bomworksetid INTEGER;
  _temp INTEGER;
  _bomitemid INTEGER;

BEGIN

  SELECT createBOMItem( pBomitemid, pParentItemid, pComponentItemid,
                        pSeqNumber, pIssueMethod,
                        pUomId, pQtyFxd, pQtyPer, pScrap,
                        pEffective, pExpires,
                        pCreateWo, pBOOItemseqid, pSchedAtWooper, pECN, pSubType, pRevisionid, pCharId, pCharVal, NULL, NULL ) INTO _bomitemid;

  RETURN _bomitemid;
  
END;

Function: public.createbomitem(integer, integer, integer, integer, bpchar, integer, numeric, numeric, numeric, date, date, boolean, integer, boolean, text, bpchar, integer, integer, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  pParentItemid ALIAS FOR $2;
  pComponentItemid ALIAS FOR $3;
  pSeqNumber ALIAS FOR $4;
  pIssueMethod ALIAS FOR $5;
  pUomId ALIAS FOR $6;
  pQtyFxd ALIAS FOR $7;
  pQtyPer ALIAS FOR $8;
  pScrap ALIAS FOR $9;
  pEffective ALIAS FOR $10;
  pExpires ALIAS FOR $11;
  pCreateWo ALIAS FOR $12;
  pBOOItemseqid ALIAS FOR $13;
  pSchedAtWooper ALIAS FOR $14;
  pECN ALIAS FOR $15;
  pSubType ALIAS FOR $16;
  pRevisionid ALIAS FOR $17;
  pCharId ALIAS FOR $18;
  pCharVal ALIAS FOR $19;
  pNotes ALIAS FOR $20;
  pRef ALIAS FOR $21;
  _bomworksetid INTEGER;
  _temp INTEGER;

BEGIN

--  Make sure that the parent and component are not the same
  IF (pParentItemid = pComponentItemid) THEN
    RETURN -1;
  END IF;

--  Make sure that the parent is not used in the component at some level
  IF ( SELECT (item_type IN ('M', 'F'))
       FROM item
       WHERE (item_id=pComponentItemid) ) THEN
    SELECT indentedWhereUsed(pParentItemid) INTO _bomworksetid;
    SELECT bomwork_id INTO _temp
    FROM bomwork
    WHERE ( (bomwork_set_id=_bomworksetid)
     AND (bomwork_item_id=pComponentItemid) )
    LIMIT 1;
    IF (FOUND) THEN
      PERFORM deleteBOMWorkset(_bomworksetid);
      RETURN -2;
    END IF;
  END IF;

  PERFORM deleteBOMWorkset(_bomworksetid);

--  Create the BOM Item
  INSERT INTO bomitem
  ( bomitem_id, bomitem_parent_item_id, bomitem_item_id,
    bomitem_seqnumber, bomitem_issuemethod,
    bomitem_uom_id, bomitem_qtyfxd, bomitem_qtyper, bomitem_scrap,
    bomitem_effective, bomitem_expires,
    bomitem_createwo,
    bomitem_booitem_seq_id, bomitem_schedatwooper,
    bomitem_ecn, bomitem_subtype, bomitem_moddate, bomitem_rev_id,
    bomitem_char_id, bomitem_value, bomitem_notes, bomitem_ref )
  VALUES
  ( pBomitemid, pParentItemid, pComponentItemid,
    pSeqNumber, pIssueMethod,
    pUomId, pQtyFxd, pQtyPer, pScrap,
    pEffective, pExpires,
    pCreateWo,
    pBOOItemseqid, COALESCE(pSchedAtWooper, FALSE),
    pECN, pSubType, CURRENT_DATE, pRevisionid,
    pCharId,pCharVal,pNotes, pRef );

  RETURN pBomitemid;

END;

Function: public.createcheck(integer, text, integer, date, numeric, integer, integer, integer, text, text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid		ALIAS FOR  $1;
  pRecipType		ALIAS FOR  $2;
  pRecipId		ALIAS FOR  $3;
  pCheckDate		ALIAS FOR  $4;
  pAmount		ALIAS FOR  $5;
  pCurrid		ALIAS FOR  $6;
  pExpcatid		ALIAS FOR  $7;
  _journalNumber	INTEGER := $8;
  pFor			ALIAS FOR  $9;
  pNotes		ALIAS FOR $10;
  pMisc			ALIAS FOR $11;
  _checkid INTEGER;
BEGIN

  SELECT createCheck(pBankaccntid,pRecipType,pRecipId,pCheckDate,pAmount,pCurrid,pExpcatid,_journalNumber,pFor,pNotes,pMisc,NULL) INTO _checkid;
  RETURN _checkid;

END;

Function: public.createcheck(integer, text, integer, date, numeric, integer, integer, integer, text, text, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid		ALIAS FOR  $1;
  pRecipType		ALIAS FOR  $2;
  pRecipId		ALIAS FOR  $3;
  pCheckDate		ALIAS FOR  $4;
  pAmount		ALIAS FOR  $5;
  pCurrid		ALIAS FOR  $6;
  pExpcatid		ALIAS FOR  $7;
  _journalNumber	INTEGER := $8;
  pFor			ALIAS FOR  $9;
  pNotes		ALIAS FOR $10;
  pMisc			ALIAS FOR $11;
  pAropenid             ALIAS FOR $12;
  _checkid		INTEGER;
  _check_curr_rate      NUMERIC;
  _bankaccnt_currid	INTEGER;

BEGIN
  SELECT bankaccnt_curr_id,currRate(bankaccnt_curr_id,pCheckDate) INTO _bankaccnt_currid, _check_curr_rate
  FROM bankaccnt
  WHERE bankaccnt_id = pBankaccntid;
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  IF (pRecipType NOT IN ('C', 'T', 'V')) THEN
    RETURN -2;
  END IF;

  IF (pCheckDate IS NULL) THEN
    RETURN -3;
  END IF;

  IF (pAmount <= 0) THEN
    RETURN -4;
  END IF;

  IF (pCurrid IS NULL
      OR NOT EXISTS(SELECT * FROM curr_symbol WHERE (curr_id=pCurrid))) THEN
    RETURN -5;
  END IF;

  IF (pExpcatid IS NOT NULL
      AND NOT EXISTS(SELECT * FROM expcat WHERE (expcat_id=pExpcatid))) THEN
    RETURN -6;
  END IF;

-- Do not assign Journal Number until check is posted
--  if (_journalNumber IS NULL) THEN
--    _journalNumber := fetchJournalNumber('AP-CK');
--  END IF;

  _checkid := NEXTVAL('checkhead_checkhead_id_seq');

  INSERT INTO checkhead
  ( checkhead_id,		checkhead_recip_type,	checkhead_recip_id,
    checkhead_bankaccnt_id,	checkhead_number,
    checkhead_amount,
    checkhead_checkdate,	checkhead_misc,		checkhead_expcat_id,
    checkhead_journalnumber,	checkhead_for,		checkhead_notes,
    checkhead_curr_id )
  VALUES
  ( _checkid,			pRecipType,		pRecipId,
    pBankaccntid,		-1, --fetchNextCheckNumber(pBankaccntid),
    currToCurr(pCurrid, _bankaccnt_currid, pAmount, pCheckDate),
    pCheckDate,			COALESCE(pMisc, FALSE),	pExpcatid,
    _journalNumber,		pFor,			pNotes,
    _bankaccnt_currid );

  IF (pAropenid IS NOT NULL AND fetchmetricbool('EnableReturnAuth')) THEN
    INSERT INTO checkitem (checkitem_checkhead_id,checkitem_amount,checkitem_discount,checkitem_ponumber,
                           checkitem_aropen_id,checkitem_docdate,checkitem_curr_id,checkitem_cmnumber,
                           checkitem_ranumber, checkitem_curr_rate)
    SELECT _checkid, currToCurr(checkhead_curr_id, aropen_curr_id, pAmount, checkhead_checkdate),
      0,cmhead_custponumber,pAropenid,aropen_docdate,aropen_curr_id,cmhead_number,rahead_number,
      1 / (_check_curr_rate / aropen_curr_rate)
    FROM checkhead, aropen
      LEFT OUTER JOIN cmhead ON (aropen_docnumber=cmhead_number)
      LEFT OUTER JOIN rahead ON (cmhead_rahead_id=rahead_id)
    WHERE ((aropen_id=pAropenid)
     AND (checkhead_id=_checkid));
  ELSIF (pAropenid IS NOT NULL) THEN
    INSERT INTO checkitem (checkitem_checkhead_id,checkitem_amount,checkitem_discount,checkitem_ponumber,
                           checkitem_aropen_id,checkitem_docdate,checkitem_curr_id,checkitem_cmnumber,
                           checkitem_ranumber, checkitem_curr_rate)
    SELECT _checkid,currToCurr(checkhead_curr_id, aropen_curr_id, pAmount, checkhead_checkdate),
      0,cmhead_custponumber,pAropenid,aropen_docdate,aropen_curr_id,cmhead_number,NULL,
      1 / (_check_curr_rate / aropen_curr_rate)
    FROM checkhead, aropen
      LEFT OUTER JOIN cmhead ON (aropen_docnumber=cmhead_number)
    WHERE ((aropen_id=pAropenid)
     AND (checkhead_id=_checkid));
  END IF;
  

  RETURN _checkid;

END;

Function: public.createchecks(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid ALIAS FOR $1;
  pCheckDate ALIAS FOR $2;
  _v RECORD;
  _r RECORD;
  _c RECORD;
  _checkid		INTEGER;
  _counter		INTEGER := 0;
  _check_curr_id	INTEGER;
  _check_curr_rate      NUMERIC;

BEGIN

  SELECT bankaccnt_curr_id, currRate(bankaccnt_curr_id, pCheckDate) 
    INTO _check_curr_id, _check_curr_rate
    FROM bankaccnt
    WHERE ( bankaccnt_id = pBankaccntid );
  FOR _v IN SELECT DISTINCT vend_id, vend_number, vend_name
              FROM apselect
              JOIN apopen   ON (apselect_apopen_id=apopen_id)
              JOIN vendinfo ON (apopen_vend_id=vend_id)
            WHERE ((apselect_bankaccnt_id=pBankaccntid)
               AND (apselect_date <= pCheckDate)) LOOP

    -- if we owe this vendor anything (we might not) then create a check
    IF ((SELECT 
                SUM(apselect_amount * _check_curr_rate / apopen_curr_rate)          
	 FROM apselect, apopen
	 WHERE ((apselect_apopen_id=apopen_id)
	   AND  (apopen_vend_id=_v.vend_id)
	   AND  (apselect_bankaccnt_id=pBankaccntid)) ) > 0) THEN
      -- 0.01 is a temporary amount; we''ll update the check amount later
      _checkid := createCheck(pBankaccntid,	'V',	_v.vend_id,
			      pCheckDate,		0.01,	_check_curr_id,
			      NULL,		NULL, '',	'',	FALSE);

      FOR _r IN SELECT apopen_id, apselect_id,
		       apopen_docnumber, apopen_invcnumber, apopen_ponumber,
		       apopen_docdate, apselect_curr_id,
		       apselect_amount, apselect_discount
		FROM apselect, apopen
		WHERE ( (apselect_apopen_id=apopen_id)
		 AND (apopen_vend_id=_v.vend_id)
		 AND (apselect_bankaccnt_id=pBankaccntid) ) LOOP
	INSERT INTO checkitem
	( checkitem_checkhead_id, checkitem_apopen_id,
	  checkitem_vouchernumber, checkitem_invcnumber, checkitem_ponumber,
	  checkitem_amount, checkitem_discount, checkitem_docdate,
          checkitem_curr_id, checkitem_curr_rate )
	VALUES
	( _checkid, _r.apopen_id,
	  _r.apopen_docnumber, _r.apopen_invcnumber, _r.apopen_ponumber,
	  _r.apselect_amount, _r.apselect_discount, _r.apopen_docdate,
	  _r.apselect_curr_id, 
          1 / (_check_curr_rate / currRate(_r.apselect_curr_id, pCheckdate))  );

	DELETE FROM apselect
	WHERE (apselect_id=_r.apselect_id);

      END LOOP;

      -- one check can pay for purchases on multiple dates in multiple currencies
      UPDATE checkhead
      SET checkhead_amount = (SELECT SUM(checkitem_amount / checkitem_curr_rate)
			      FROM checkitem
			      WHERE (checkitem_checkhead_id=checkhead_id))
      WHERE (checkhead_id=_checkid);

      _counter := (_counter + 1);
    END IF;

  END LOOP;

  RETURN _counter;

END;

Function: public.createcounttag(integer, text, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pComments ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pFreeze ALIAS FOR $4;
BEGIN
  RETURN createCountTag(pItemsiteid, pComments, pPriority, pFreeze, NULL);
END;

Function: public.createcounttag(integer, text, boolean, boolean, integer)

Returns: integer

Language: PLPGSQL


-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pComments ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pFreeze ALIAS FOR $4;
  pLocationid ALIAS FOR $5;
  _invcntid INTEGER;
  _whs		RECORD;
  _type CHARACTER;
  _controlmethod        CHARACTER;

BEGIN

  SELECT item_type, itemsite_controlmethod INTO _type, _controlmethod
    FROM itemsite, item
   WHERE ((itemsite_item_id=item_id)
     AND  (itemsite_id=pItemsiteid));

  IF (NOT FOUND OR _type IN ('F', 'R', 'L','J') OR _controlmethod = 'N') THEN
    RETURN 0; -- We simply do not do these item types.
  END IF;

  -- Test for existing tags
   IF (pLocationid IS NULL) THEN
       SELECT invcnt_id INTO _invcntid
       FROM invcnt
       WHERE ((NOT invcnt_posted)
       AND (invcnt_location_id IS NULL)
       AND (invcnt_itemsite_id=pItemsiteid));
  
  ELSE

    SELECT invcnt_id INTO _invcntid
     FROM invcnt
     WHERE ((NOT invcnt_posted)
     AND (invcnt_itemsite_id=pItemsiteid)
     AND (invcnt_location_id=pLocationid));
  END IF;

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('invcnt_invcnt_id_seq') INTO _invcntid;

    SELECT whsinfo.* INTO _whs
      FROM whsinfo, itemsite
     WHERE ((warehous_id=itemsite_warehous_id)
       AND  (itemsite_id=pItemsiteid));

    INSERT INTO invcnt (
      invcnt_id, invcnt_itemsite_id, invcnt_tagdate,
      invcnt_tagnumber,
      invcnt_tag_username, invcnt_posted,
      invcnt_priority, invcnt_comments, invcnt_location_id
    ) VALUES (
      _invcntid, pItemsiteid, CURRENT_TIMESTAMP,
      (_whs.warehous_counttag_prefix || _whs.warehous_counttag_number::TEXT),
      getEffectiveXtUser(), FALSE,
      pPriority, pComments, pLocationid
    );

    UPDATE whsinfo
    SET warehous_counttag_number=(warehous_counttag_number + 1)
    WHERE (warehous_id=_whs.warehous_id);

    IF (pFreeze) THEN
      UPDATE itemsite
      SET itemsite_freeze=TRUE
      WHERE (itemsite_id=pItemsiteid);
    END IF;

  END IF;

  RETURN _invcntid;
END;

Function: public.createcustomer(integer)

Returns: integer

Language: PLPGSQL

  DECLARE
    pcrmacctId  ALIAS FOR $1;
    _custId     INTEGER := 0;
  BEGIN
    IF (pcrmacctId < 0 OR pcrmacctId IS NULL) THEN
      RETURN -1;
    END IF;

    SELECT crmacct_cust_id INTO _custId
    FROM crmacct WHERE crmacct_id = pcrmacctId;

    IF (_custId IS NOT NULL AND _custId <= 0) THEN
      RETURN -2;
    END IF;

    INSERT INTO _customer (active, customer_number, customer_name)
      SELECT crmacct_active, crmacct_number, crmacct_name
      FROM crmacct
      WHERE crmacct_id = pcrmacctId;
    _custId := CURRVAL('cust_cust_id_seq');

    UPDATE crmacct SET crmacct_prospect_id = NULL, crmacct_cust_id = _custId
    WHERE crmacct_id = pcrmacctId;

    RETURN _custId;
  END;

Function: public.createcyclecountsbywarehouse(integer, integer, integer, text, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pClasscodeid ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
BEGIN
  RETURN createCycleCountsByWarehouseByClassCode(pWarehousid, pClasscodeid, pMaxNumber, pComments, pPriority, pFreeze, NULL, FALSE);
END;

Function: public.createcyclecountsbywarehouse(integer, integer, text, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pMaxNumber ALIAS FOR $2;
  pComments ALIAS FOR $3;
  pPriority ALIAS FOR $4;
  pFreeze ALIAS FOR $5;

BEGIN
  RETURN createCycleCountsByWarehouse(pWarehousid, pMaxNumber, pComments, pPriority, pFreeze, NULL, FALSE);
END;

Function: public.createcyclecountsbywarehouse(integer, integer, text, boolean, boolean, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pMaxNumber ALIAS FOR $2;
  pComments ALIAS FOR $3;
  pPriority ALIAS FOR $4;
  pFreeze ALIAS FOR $5;
  pLocationid ALIAS FOR $6;
  pIgnoreZeroBalance ALIAS FOR $7;
  _itemsites RECORD;
  _returnVal	INTEGER;
  
BEGIN

IF (pLocationid IS NULL) THEN
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, itemsite_qtyonhand
                    FROM itemsite, item
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND (itemsite_id NOT IN ( SELECT invcnt_itemsite_id
                                               FROM invcnt, itemsite
                                               WHERE ( (invcnt_itemsite_id=itemsite_id)
                                                AND (itemsite_warehous_id=pWarehousid)
						AND (invcnt_location_id IS NULL)
                                                AND (NOT invcnt_posted) ) ) )
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND ((pLocationid IS NULL) OR (validLocation(pLocationid, itemsite_id)))
                     AND (itemsite_warehous_id=pWarehousid) )
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass, item_number

LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;            

ELSE
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, SUM(itemloc_qty)
                    FROM itemsite, itemloc
                    WHERE ( (itemsite_active)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND (pLocationid = itemloc_location_id)
                     AND (itemloc_itemsite_id = itemsite_id)
                     AND (itemsite_warehous_id=pWarehousid) )
		    GROUP BY itemsite_id, itemsite_warehous_id,
			     itemsite_datelastcount, itemsite_cyclecountfreq,
			     itemsite_abcclass
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass

LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;  
                   
END IF;

  RETURN 0;
END;

Function: public.createcyclecountsbywarehouse(integer, text, integer, text, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pClasscodePattern ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
BEGIN
  RETURN createCycleCountsByWarehouseByClassCode(pWarehousid, pClasscodePattern, pMaxNumber, pComments, pPriority, pFreeze, NULL, FALSE);
END;

Function: public.createcyclecountsbywarehousebyclasscode(integer, integer, integer, text, boolean, boolean, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pClasscodeid ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
  pLocationid ALIAS FOR $7;
  pIgnoreZeroBalance ALIAS FOR $8;
  _itemsites RECORD;
  _returnVal	INTEGER;
  
BEGIN

IF (pLocationid IS NULL) THEN
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, itemsite_qtyonhand
                    FROM itemsite, item
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND (itemsite_id NOT IN ( SELECT invcnt_itemsite_id
                                               FROM invcnt, itemsite
                                               WHERE ( (invcnt_itemsite_id=itemsite_id)
                                                AND (itemsite_warehous_id=pWarehousid)
						AND (invcnt_location_id IS NULL)
                                                AND (NOT invcnt_posted) ) ) )
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND ((pLocationid IS NULL) OR (validLocation(pLocationid, itemsite_id)))
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (item_classcode_id=pClasscodeid) )
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass, item_number
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

ELSE
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, SUM(itemloc_qty)
                    FROM itemsite, item, itemloc
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND (pLocationid = itemloc_location_id)
                     AND (itemloc_itemsite_id = itemsite_id)
                     AND (itemsite_warehous_id=pWarehousid) 
                     AND (item_classcode_id=pClasscodeid) )
		    GROUP BY itemsite_id, itemsite_warehous_id,
			     itemsite_datelastcount, itemsite_cyclecountfreq,
			     itemsite_abcclass
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

END IF;

  RETURN 0;
END;

Function: public.createcyclecountsbywarehousebyclasscode(integer, text, integer, text, boolean, boolean, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pClasscodePattern ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
  pLocationid ALIAS FOR $7;
  pIgnoreZeroBalance ALIAS FOR $8;
  _itemsites RECORD;
  _returnVal	INTEGER;
  
BEGIN

IF (pLocationid IS NULL) THEN
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, itemsite_qtyonhand
                    FROM itemsite, item, classcode
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (item_classcode_id=classcode_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND (itemsite_id NOT IN ( SELECT invcnt_itemsite_id
                                               FROM invcnt, itemsite
                                               WHERE ( (invcnt_itemsite_id=itemsite_id)
                                                AND (itemsite_warehous_id=pWarehousid)
						AND (invcnt_location_id IS NULL)
                                                AND (NOT invcnt_posted) ) ) )
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND ((pLocationid IS NULL) OR (validLocation(pLocationid, itemsite_id)))
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (classcode_code ~ pClasscodePattern) )
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass, item_number
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

ELSE
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, SUM(itemloc_qty)
                    FROM itemsite, item, classcode, itemloc
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (item_classcode_id=classcode_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND (pLocationid = itemloc_location_id)
                     AND (itemloc_itemsite_id = itemsite_id)
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (classcode_code ~ pClasscodePattern) )
		    GROUP BY itemsite_id, itemsite_warehous_id,
			     itemsite_datelastcount, itemsite_cyclecountfreq,
			     itemsite_abcclass
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

END IF;

  RETURN 0;
END;

Function: public.createcyclecountsbywarehousebyplannercode(integer, integer, integer, text, boolean, boolean, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pPlancodeid ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
  pLocationid ALIAS FOR $7;
  pIgnoreZeroBalance ALIAS FOR $8;
  _itemsites RECORD;
  _returnVal	INTEGER;
  
BEGIN

IF (pLocationid IS NULL) THEN
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, itemsite_qtyonhand
                    FROM itemsite, item
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND (itemsite_id NOT IN ( SELECT invcnt_itemsite_id
                                               FROM invcnt, itemsite
                                               WHERE ( (invcnt_itemsite_id=itemsite_id)
                                                AND (itemsite_warehous_id=pWarehousid)
						AND (invcnt_location_id IS NULL)
                                                AND (NOT invcnt_posted) ) ) )
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND ((pLocationid IS NULL) OR (validLocation(pLocationid, itemsite_id)))
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (itemsite_plancode_id=pPlancodeid) )
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass, item_number
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

ELSE
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, SUM(itemloc_qty)
                    FROM itemsite, itemloc
                    WHERE ( (itemsite_active)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND (itemloc_itemsite_id = itemsite_id)
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (pLocationid = itemloc_location_id)
                     AND (itemsite_plancode_id=pPlancodeid) )
		    GROUP BY itemsite_id, itemsite_warehous_id,
			     itemsite_datelastcount, itemsite_cyclecountfreq,
			     itemsite_abcclass
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

END IF;

  RETURN 0;
END;

Function: public.createcyclecountsbywarehousebyplannercode(integer, text, integer, text, boolean, boolean, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pPlancodePattern ALIAS FOR $2;
  pMaxNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pPriority ALIAS FOR $5;
  pFreeze ALIAS FOR $6;
  pLocationid ALIAS FOR $7;
  pIgnoreZeroBalance ALIAS FOR $8;
  _itemsites RECORD;
  _returnVal	INTEGER;
  
BEGIN

IF (pLocationid IS NULL) THEN
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, itemsite_qtyonhand
                    FROM itemsite, item, plancode
                    WHERE ( (itemsite_active)
                     AND (itemsite_item_id=item_id)
                     AND (itemsite_plancode_id=plancode_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND (itemsite_id NOT IN ( SELECT invcnt_itemsite_id
                                               FROM invcnt, itemsite
                                               WHERE ( (invcnt_itemsite_id=itemsite_id)
                                                AND (itemsite_warehous_id=pWarehousid)
						AND (invcnt_location_id IS NULL)
                                                AND (NOT invcnt_posted) ) ) )
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND ((pLocationid IS NULL) OR (validLocation(pLocationid, itemsite_id)))
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (plancode_code ~ pPlancodePattern) )
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass, item_number
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

ELSE
  FOR _itemsites IN SELECT itemsite_id, itemsite_warehous_id, SUM(itemloc_qty)
                    FROM itemsite, plancode, itemloc
                    WHERE ( (itemsite_active)
                     AND (itemsite_plancode_id=plancode_id)
                     AND (itemsite_cyclecountfreq > 0)
                     AND ((COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq) < CURRENT_DATE)
                     AND ((NOT pIgnoreZeroBalance) OR (itemsite_qtyonhand <> 0))
                     AND (pLocationid = itemloc_location_id)
                     AND (itemloc_itemsite_id = itemsite_id)
                     AND (itemsite_warehous_id=pWarehousid)
                     AND (plancode_code ~ pPlancodePattern) )
		    GROUP BY itemsite_id, itemsite_warehous_id,
			     itemsite_datelastcount, itemsite_cyclecountfreq,
			     itemsite_abcclass
                    ORDER BY (COALESCE(itemsite_datelastcount, startOfTime()) + itemsite_cyclecountfreq), itemsite_abcclass
                    LIMIT pMaxNumber LOOP
    _returnVal := createCountTag(_itemsites.itemsite_id, pComments,
				    pPriority, pFreeze, pLocationid);
    IF (_returnVal < 0) THEN
      RETURN _returnVal;
    END IF;
  END LOOP;

END IF;

  RETURN 0;
END;

Function: public.createfile(text, text, bytea)

Returns: integer

Language: PLPGSQL

declare
  pTitle ALIAS FOR $1;
  pDescription ALIAS FOR $2;
  pStream ALIAS FOR $3;
  _id integer;
begin
  _id := nextval('file_file_id_seq');
  insert into file (file_id, file_title, file_descrip, file_stream) values (_id, pTitle, pDescription, pStream);
  return _id;
end;

Function: public.createinvoice(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;
  _invcheadid INTEGER;
  _invcitemid INTEGER;
  _qtyToInvoice	NUMERIC;
  _r		RECORD;
  _s		RECORD;
  _lastlinenumber INTEGER := 1;
  
BEGIN

  IF ( ( SELECT cobmisc_posted
         FROM cobmisc
         WHERE (cobmisc_id=pCobmiscid) ) ) THEN
    RETURN -1;
  END IF;

  SELECT NEXTVAL('invchead_invchead_id_seq') INTO _invcheadid;

--  Give this selection a number if it has not been assigned one
  UPDATE cobmisc
  SET cobmisc_invcnumber=fetchInvcNumber()
  WHERE ( (cobmisc_invcnumber IS NULL)
   AND (cobmisc_id=pCobmiscid) );

--  Create the Invoice header
  INSERT INTO invchead
  ( 
	invchead_id,invchead_cust_id,invchead_shipto_id,invchead_ordernumber,invchead_orderdate,
	invchead_posted,invchead_printed,invchead_invcnumber,invchead_invcdate,invchead_shipdate,
	invchead_ponumber,invchead_shipvia,invchead_fob,invchead_billto_name,invchead_billto_address1,
	invchead_billto_address2,invchead_billto_address3,invchead_billto_city,invchead_billto_state,invchead_billto_zipcode,
	invchead_billto_phone,invchead_billto_country,invchead_shipto_name,invchead_shipto_address1,invchead_shipto_address2,
	invchead_shipto_address3,invchead_shipto_city,invchead_shipto_state,invchead_shipto_zipcode,invchead_shipto_phone,
	invchead_shipto_country,invchead_salesrep_id,invchead_commission,invchead_terms_id,invchead_freight,
	invchead_misc_amount,invchead_misc_descrip,invchead_misc_accnt_id,invchead_payment,
	invchead_paymentref,invchead_notes,invchead_prj_id,invchead_curr_id,
	invchead_taxzone_id, invchead_shipchrg_id,
        invchead_saletype_id, invchead_shipzone_id
   )
  SELECT 
	_invcheadid,cohead_cust_id,cohead_shipto_id,cohead_number,cohead_orderdate,
	FALSE,FALSE,cobmisc_invcnumber,cobmisc_invcdate,cobmisc_shipdate,
	cohead_custponumber,cobmisc_shipvia,cohead_fob,cohead_billtoname,cohead_billtoaddress1,
	cohead_billtoaddress2,cohead_billtoaddress3,cohead_billtocity,cohead_billtostate,cohead_billtozipcode,
	cntct_phone AS cust_phone,cohead_billtocountry,cohead_shiptoname,cohead_shiptoaddress1,cohead_shiptoaddress2,
	cohead_shiptoaddress3,cohead_shiptocity,cohead_shiptostate,cohead_shiptozipcode,cohead_shipto_cntct_phone,
	cohead_shiptocountry,cohead_salesrep_id,COALESCE(cohead_commission,0),cohead_terms_id,cobmisc_freight,
	COALESCE(cobmisc_misc, 0.00),cobmisc_misc_descrip,cobmisc_misc_accnt_id,cobmisc_payment,
	cobmisc_paymentref,cobmisc_notes,cohead_prj_id,cobmisc_curr_id,
	cobmisc_taxzone_id, cohead_shipchrg_id,
        cohead_saletype_id, cohead_shipzone_id
    FROM cobmisc, cohead, custinfo
    LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
  WHERE ( (cobmisc_cohead_id=cohead_id)
   AND (cohead_cust_id=cust_id)
   AND (cobmisc_id=pCobmiscid) );

	INSERT INTO invcheadtax(taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id, taxhist_basis, 
			taxhist_basis_tax_id, taxhist_sequence, taxhist_percent, taxhist_amount, taxhist_tax, taxhist_docdate)
        SELECT _invcheadid,taxhist_taxtype_id, taxhist_tax_id, taxhist_basis, 
			taxhist_basis_tax_id, taxhist_sequence, taxhist_percent, taxhist_amount, taxhist_tax, taxhist_docdate
        FROM cobmisctax 
	WHERE taxhist_parent_id = pCobmiscid 
	AND taxhist_taxtype_id = getadjustmenttaxtypeid();

--  Create the Invoice items
  FOR _r IN SELECT coitem_id, coitem_linenumber, coitem_subnumber, coitem_custpn,
                   coitem_qtyord, cobill_qty,
                   coitem_qty_uom_id, coitem_qty_invuomratio,
                   coitem_custprice, coitem_price,
                   coitem_price_uom_id, coitem_price_invuomratio,
                   coitem_memo, coitem_rev_accnt_id,
                   itemsite_item_id, itemsite_warehous_id,
                   cobill_taxtype_id,
                   formatSoItemNumber(coitem_id) AS ordnumber
            FROM coitem, cobill, itemsite
            WHERE ( (cobill_coitem_id=coitem_id)
             AND (coitem_itemsite_id=itemsite_id)
             AND (cobill_cobmisc_id=pCobmiscid) )
            ORDER BY coitem_linenumber, coitem_subnumber LOOP

    SELECT NEXTVAL('invcitem_invcitem_id_seq') INTO _invcitemid;
    INSERT INTO invcitem
    ( invcitem_id, invcitem_invchead_id,
      invcitem_linenumber, invcitem_item_id, invcitem_warehous_id,
      invcitem_custpn, invcitem_number, invcitem_descrip,
      invcitem_ordered, invcitem_billed,
      invcitem_qty_uom_id, invcitem_qty_invuomratio,
      invcitem_custprice, invcitem_price,
      invcitem_price_uom_id, invcitem_price_invuomratio,
      invcitem_notes, invcitem_taxtype_id,
      invcitem_coitem_id, invcitem_rev_accnt_id )
    VALUES
    ( _invcitemid, _invcheadid,
      _lastlinenumber,
      _r.itemsite_item_id, _r.itemsite_warehous_id,
      _r.coitem_custpn, '', '',
      _r.coitem_qtyord, _r.cobill_qty,
      _r.coitem_qty_uom_id, _r.coitem_qty_invuomratio,
      _r.coitem_custprice, _r.coitem_price,
      _r.coitem_price_uom_id, _r.coitem_price_invuomratio,
      _r.coitem_memo, _r.cobill_taxtype_id,
      _r.coitem_id, _r.coitem_rev_accnt_id );

--  Find and mark any Lot/Serial invdetail records associated with this bill
    UPDATE invdetail SET invdetail_invcitem_id = _invcitemid
     WHERE (invdetail_id IN (SELECT invdetail_id
                               FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
                              WHERE ( (invhist_ordnumber = _r.ordnumber)
                                AND   (invhist_ordtype = 'SO')
                                AND   (invhist_transtype = 'SH')
                                AND   (invdetail_invcitem_id IS NULL) ) ));

--  Mark any shipped, uninvoiced shipitems for the current coitem as invoiced
    _qtyToInvoice :=  _r.cobill_qty;
    FOR _s IN SELECT shipitem.*, shipitem_qty = _r.cobill_qty AS matched
	      FROM shipitem, shiphead
	      WHERE ((shipitem_shiphead_id=shiphead_id)
	        AND  (shipitem_orderitem_id=_r.coitem_id)
	        AND  (shiphead_shipped)
		AND  (shiphead_order_type='SO')
	        AND  (NOT shipitem_invoiced))
	      ORDER BY matched DESC, shipitem_qty DESC FOR UPDATE LOOP
      IF (_qtyToInvoice >= _s.shipitem_qty) THEN
	UPDATE shipitem
	SET shipitem_invoiced=TRUE, shipitem_invcitem_id=_invcitemid
	WHERE (shipitem_id=_s.shipitem_id);
	_qtyToInvoice := _qtyToInvoice - _s.shipitem_qty;
      END IF;
      IF (_qtyToInvoice <= 0) THEN
	EXIT;
      END IF;
    END LOOP;

    UPDATE cobill SET cobill_invcnum=cobmisc_invcnumber,
		      cobill_invcitem_id=invcitem_id
    FROM invcitem, coitem, cobmisc
    WHERE ((invcitem_linenumber=_lastlinenumber)
      AND  (coitem_id=cobill_coitem_id)
      AND  (cobmisc_id=cobill_cobmisc_id)
      AND  (cobill_cobmisc_id=pCobmiscid)
      AND  (invcitem_invchead_id=_invcheadid));
    
    _lastlinenumber := _lastlinenumber + 1;

  END LOOP;

--  Close all requested coitem's
  IF ( ( SELECT cobmisc_closeorder
         FROM cobmisc
         WHERE (cobmisc_id=pCobmiscid) ) ) THEN
    UPDATE coitem
    SET coitem_status='C'
    FROM cobmisc
    WHERE ( (coitem_status NOT IN ('C', 'X'))
     AND (coitem_cohead_id=cobmisc_cohead_id)
     AND (cobmisc_id=pCobmiscid) );
  ELSE
    UPDATE coitem
    SET coitem_status='C'
    FROM cobill
    WHERE ( (cobill_coitem_id=coitem_id)
     AND (coitem_status <> 'X')
     AND (cobill_toclose)
     AND (cobill_cobmisc_id=pCobmiscid) );
  END IF;

--  Mark the cobmisc as posted
  UPDATE cobmisc
  SET cobmisc_posted=TRUE, cobmisc_invchead_id=_invcheadid
  WHERE (cobmisc_id=pCobmiscid);

--  All done
  RETURN _invcheadid;

END;

Function: public.createinvoiceconsolidated(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _invcheadid INTEGER;
  _invcitemid INTEGER;
  _qtyToInvoice	NUMERIC;
  _r		RECORD;
  _s		RECORD;
  _c		RECORD;
  _i		RECORD;
  _count      INTEGER;
  _invcnumber INTEGER;
  _lastlinenumber INTEGER;

BEGIN
  _count := 0;

  FOR _c IN SELECT min(cobmisc_id) AS cobmisc_id, count(*) AS cnt,
-- there are the key values for consolidation
                   cohead_billtoname, cohead_billtoaddress1,
                   cohead_billtoaddress2, cohead_billtoaddress3,
                   cohead_billtocity, cohead_billtostate,
                   cohead_billtozipcode, cntct_phone AS cust_phone,
                   cohead_billtocountry,
                   cohead_salesrep_id, cohead_commission,
                   cohead_terms_id,
                   cobmisc_misc_accnt_id,
                   cohead_prj_id, cobmisc_curr_id,
                   cobmisc_taxzone_id,
                   cohead_shipchrg_id,
                   cohead_saletype_id,
                   cohead_shipzone_id,
                   
		-- the following are consolidated values to use in creating the header
                   MIN(cohead_number) AS cohead_number,
                   MIN(cohead_orderdate) AS cohead_orderdate,
                   MIN(cobmisc_invcdate) AS cobmisc_invcdate,
                   MIN(cobmisc_shipdate) AS cobmisc_shipdate,
                   SUM(cobmisc_freight) AS cobmisc_freight,
                   SUM(cobmisc_misc) AS cobmisc_misc,
                   SUM(cobmisc_payment) AS cobmisc_payment
                   
              FROM cobmisc
              JOIN cohead   ON (cobmisc_cohead_id=cohead_id)
              JOIN custinfo ON (cohead_cust_id=cust_id)
              LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
             WHERE(NOT cobmisc_posted
               AND (cohead_cust_id=pCustid)
               )
          GROUP BY cohead_billtoname, cohead_billtoaddress1,
                   cohead_billtoaddress2, cohead_billtoaddress3,
                   cohead_billtocity, cohead_billtostate,
                   cohead_billtozipcode, cust_phone,
                   cohead_billtocountry,
                   cohead_salesrep_id, cohead_commission,
                   cohead_terms_id,
                   cobmisc_misc_accnt_id,
                   cohead_prj_id, cobmisc_curr_id,
                   cobmisc_taxzone_id,
                   cohead_shipchrg_id,
                   cohead_saletype_id,
                   cohead_shipzone_id
		LOOP

    IF(_c.cnt = 1) THEN
      PERFORM createInvoice(_c.cobmisc_id);
      _count := (_count + 1);
    ELSE
      SELECT NEXTVAL('invchead_invchead_id_seq'), fetchInvcNumber() INTO _invcheadid, _invcnumber;
  
  --  Create the Invoice header
      INSERT INTO invchead
      ( invchead_id, invchead_cust_id, invchead_shipto_id,
        invchead_ordernumber, invchead_orderdate,
        invchead_posted, invchead_printed,
        invchead_invcnumber, invchead_invcdate, invchead_shipdate,
        invchead_ponumber, invchead_shipvia, invchead_fob,
        invchead_billto_name, invchead_billto_address1,
        invchead_billto_address2, invchead_billto_address3,
        invchead_billto_city, invchead_billto_state,
        invchead_billto_zipcode, invchead_billto_phone,
        invchead_billto_country,
        invchead_shipto_name, invchead_shipto_address1,
        invchead_shipto_address2, invchead_shipto_address3,
        invchead_shipto_city, invchead_shipto_state,
        invchead_shipto_zipcode, invchead_shipto_phone,
        invchead_shipto_country,
        invchead_salesrep_id, invchead_commission,
        invchead_terms_id,
        invchead_freight,
        invchead_misc_amount, invchead_misc_descrip, invchead_misc_accnt_id,
        invchead_payment, invchead_paymentref,
        invchead_notes, invchead_prj_id, invchead_curr_id,
        invchead_taxzone_id,
        invchead_shipchrg_id,
        invchead_saletype_id, invchead_shipzone_id )
      VALUES(_invcheadid,
             pCustid, -1,
             NULL, _c.cohead_orderdate,
             FALSE, FALSE,
             _invcnumber, _c.cobmisc_invcdate, _c.cobmisc_shipdate,
             'MULTIPLE', '', '',
             _c.cohead_billtoname, _c.cohead_billtoaddress1,
             _c.cohead_billtoaddress2, _c.cohead_billtoaddress3,
             _c.cohead_billtocity, _c.cohead_billtostate,
             _c.cohead_billtozipcode, _c.cust_phone,
             _c.cohead_billtocountry,
             '', '', '', '', '', '', '', '', '',
             _c.cohead_salesrep_id, COALESCE(_c.cohead_commission, 0),
             _c.cohead_terms_id,
             _c.cobmisc_freight,
             _c.cobmisc_misc, CASE WHEN(_c.cobmisc_misc <> 0) THEN 'Multiple' ELSE '' END,
             _c.cobmisc_misc_accnt_id,
             _c.cobmisc_payment, '',
             'Multiple Sales Order # Invoice', _c.cohead_prj_id, _c.cobmisc_curr_id,
             _c.cobmisc_taxzone_id,
             _c.cohead_shipchrg_id,
             _c.cohead_saletype_id, _c.cohead_shipzone_id
             );
 
    _lastlinenumber := 1;
    FOR _i IN SELECT cobmisc_id
                FROM cobmisc
                JOIN cohead   ON (cobmisc_cohead_id=cohead_id)
                JOIN custinfo ON (cohead_cust_id=cust_id)
                LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
               WHERE(NOT cobmisc_posted
                 AND (cohead_cust_id=pCustid)
                 AND (COALESCE(cohead_billtoname,'')         = COALESCE(_c.cohead_billtoname,''))
                 AND (COALESCE(cohead_billtoaddress1,'')     = COALESCE(_c.cohead_billtoaddress1,''))
                 AND (COALESCE(cohead_billtoaddress2,'')     = COALESCE(_c.cohead_billtoaddress2,''))
                 AND (COALESCE(cohead_billtoaddress3,'')     = COALESCE(_c.cohead_billtoaddress3,''))
                 AND (COALESCE(cohead_billtocity,'')         = COALESCE(_c.cohead_billtocity,''))
                 AND (COALESCE(cohead_billtostate,'')        = COALESCE(_c.cohead_billtostate,''))
                 AND (COALESCE(cohead_billtozipcode,'')      = COALESCE(_c.cohead_billtozipcode,''))
                 AND (COALESCE(cntct_phone,'')               = COALESCE(_c.cust_phone,''))
                 AND (COALESCE(cohead_billtocountry,'')      = COALESCE(_c.cohead_billtocountry,''))
                 AND (COALESCE(cohead_salesrep_id, 0)        = COALESCE(_c.cohead_salesrep_id, 0))
                 AND (COALESCE(cohead_commission, 0)         = COALESCE(_c.cohead_commission, 0))
                 AND (COALESCE(cohead_terms_id, 0)           = COALESCE(_c.cohead_terms_id, 0))
                 AND (COALESCE(cobmisc_misc_accnt_id, 0)     = COALESCE(_c.cobmisc_misc_accnt_id, 0))
                 AND (COALESCE(cohead_prj_id, 0)             = COALESCE(_c.cohead_prj_id, 0))
                 AND (COALESCE(cobmisc_curr_id, 0)           = COALESCE(_c.cobmisc_curr_id, 0))
                 AND (COALESCE(cobmisc_taxzone_id, 0)        = COALESCE(_c.cobmisc_taxzone_id, 0))
                 AND (COALESCE(cohead_saletype_id, 0)        = COALESCE(_c.cohead_saletype_id, 0))
                 AND (COALESCE(cohead_shipzone_id, 0)        = COALESCE(_c.cohead_shipzone_id, 0))
                ) LOOP

    --  Create the Invoice Head tax
        INSERT INTO invcheadtax(taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id, taxhist_basis, 
                                taxhist_basis_tax_id, taxhist_sequence, taxhist_percent, taxhist_amount, taxhist_tax, taxhist_docdate)
        SELECT _invcheadid,taxhist_taxtype_id, taxhist_tax_id, taxhist_basis, 
               taxhist_basis_tax_id, taxhist_sequence, taxhist_percent, taxhist_amount, taxhist_tax, taxhist_docdate
        FROM cobmisctax 
        WHERE taxhist_parent_id = _i.cobmisc_id
          AND taxhist_taxtype_id = getadjustmenttaxtypeid();

    --  Give this selection a number if it has not been assigned one
        UPDATE cobmisc
           SET cobmisc_invcnumber=_invcnumber
         WHERE(cobmisc_id=_i.cobmisc_id);
      
    --  Create the Invoice items
        FOR _r IN SELECT coitem_id, coitem_linenumber, coitem_subnumber, coitem_custpn,
                         coitem_qtyord, cobill_qty,
                         coitem_qty_uom_id, coitem_qty_invuomratio,
                         coitem_custprice, coitem_price,
                         coitem_price_uom_id, coitem_price_invuomratio,
                         coitem_memo,
                         itemsite_item_id, itemsite_warehous_id,
                         cobill_taxtype_id
                    FROM cohead, coitem, cobill, itemsite
                   WHERE((cobill_coitem_id=coitem_id)
                     AND (cohead_id=coitem_cohead_id)
                     AND (coitem_itemsite_id=itemsite_id)
                     AND (cobill_cobmisc_id=_i.cobmisc_id) ) 
                   ORDER BY cohead_number, coitem_linenumber, coitem_subnumber LOOP
      
          SELECT NEXTVAL('invcitem_invcitem_id_seq') INTO _invcitemid;
          INSERT INTO invcitem
          ( invcitem_id, invcitem_invchead_id,
            invcitem_linenumber, invcitem_item_id, invcitem_warehous_id,
            invcitem_custpn, invcitem_number, invcitem_descrip,
            invcitem_ordered, invcitem_billed,
            invcitem_qty_uom_id, invcitem_qty_invuomratio,
            invcitem_custprice, invcitem_price,
            invcitem_price_uom_id, invcitem_price_invuomratio,
            invcitem_notes,
            invcitem_taxtype_id,
            invcitem_coitem_id )
          VALUES
          ( _invcitemid, _invcheadid,
            _lastlinenumber,
            _r.itemsite_item_id, _r.itemsite_warehous_id,
            _r.coitem_custpn, '', '',
            _r.coitem_qtyord, _r.cobill_qty,
            _r.coitem_qty_uom_id, _r.coitem_qty_invuomratio,
            _r.coitem_custprice, _r.coitem_price,
            _r.coitem_price_uom_id, _r.coitem_price_invuomratio,
            _r.coitem_memo,
            _r.cobill_taxtype_id,
            _r.coitem_id );
          
      --  Find and mark any Lot/Serial invdetail records associated with this bill
          UPDATE invdetail SET invdetail_invcitem_id = _invcitemid
           WHERE (invdetail_id IN (SELECT invdetail_id
                                     FROM coitem, cohead, invhist, invdetail
                                    WHERE ((coitem_cohead_id=cohead_id)
                                      AND  (invdetail_invhist_id=invhist_id)
                                      AND  (invhist_ordnumber = text(cohead_number||'-'||formatSoLineNumber(coitem_id)))
                                      AND  (invdetail_invcitem_id IS NULL)
                                      AND  (coitem_id=_r.coitem_id)) ) );
      
      --  Mark any shipped, uninvoiced shipitems for the current coitem as invoiced
          _qtyToInvoice :=  _r.cobill_qty;
          FOR _s IN SELECT shipitem.*, shipitem_qty = _r.cobill_qty AS matched
	            FROM shipitem, shiphead
	            WHERE ((shipitem_shiphead_id=shiphead_id)
	              AND  (shipitem_orderitem_id=_r.coitem_id)
	              AND  (shiphead_shipped)
		      AND  (shiphead_order_type='SO')
	              AND  (NOT shipitem_invoiced))
	            ORDER BY matched DESC, shipitem_qty DESC FOR UPDATE LOOP
            IF (_qtyToInvoice >= _s.shipitem_qty) THEN
	      UPDATE shipitem
	      SET shipitem_invoiced=TRUE, shipitem_invcitem_id=_invcitemid
	      WHERE (shipitem_id=_s.shipitem_id);
	      _qtyToInvoice := _qtyToInvoice - _s.shipitem_qty;
            END IF;
            IF (_qtyToInvoice <= 0) THEN
	      EXIT;
            END IF;
          END LOOP;

          UPDATE cobill SET cobill_invcnum=cobmisc_invcnumber,
		          cobill_invcitem_id=invcitem_id
          FROM invcitem, coitem, cobmisc
          WHERE ((invcitem_linenumber=_lastlinenumber )
            AND  (coitem_id=cobill_coitem_id)
            AND  (cobmisc_id=cobill_cobmisc_id)
            AND  (cobill_cobmisc_id=_i.cobmisc_id)
            AND  (invcitem_invchead_id=_invcheadid));


          _lastlinenumber := _lastlinenumber + 1;
          
        END LOOP;
  
      --  Close all requested coitem's
        IF ( ( SELECT cobmisc_closeorder
               FROM cobmisc
               WHERE (cobmisc_id=_i.cobmisc_id) ) ) THEN
          UPDATE coitem
          SET coitem_status='C'
          FROM cobmisc
          WHERE ( (coitem_status NOT IN ('C', 'X'))
           AND (coitem_cohead_id=cobmisc_cohead_id)
           AND (cobmisc_id=_i.cobmisc_id) );
        ELSE
          UPDATE coitem
          SET coitem_status='C'
          FROM cobill
          WHERE ( (cobill_coitem_id=coitem_id)
           AND (coitem_status <> 'X')
           AND (cobill_toclose)
           AND (cobill_cobmisc_id=_i.cobmisc_id) );
        END IF;
      
      --  Mark the cobmisc as posted
        UPDATE cobmisc
        SET cobmisc_posted=TRUE, cobmisc_invchead_id=_invcheadid
        WHERE (cobmisc_id=_i.cobmisc_id);
    
      --  All done
        _count := (_count + 1);
      END LOOP;
    END IF;
  END LOOP;
  RETURN _count;
END;

Function: public.createinvoices()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _counter INTEGER;
  _cobmisc RECORD;

BEGIN

  _counter := 0;

  FOR _cobmisc IN SELECT cobmisc_id
                  FROM cobmisc
                  WHERE (NOT cobmisc_posted) LOOP

    PERFORM createinvoice(_cobmisc.cobmisc_id);
    _counter := (_counter + 1);

  END LOOP;

  RETURN _counter;
END;

Function: public.createinvoices(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN createinvoices($1, false);
END;

Function: public.createinvoices(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustTypeId ALIAS FOR $1;
  pConsolidate ALIAS FOR $2;
  _counter INTEGER;
  _tcounter INTEGER;
  _cobmisc RECORD;

BEGIN

  _counter := 0;

  IF (pConsolidate) THEN
    FOR _cobmisc IN SELECT DISTINCT cust_id
                      FROM cobmisc, cohead, custinfo
                     WHERE((NOT cobmisc_posted)
                       AND (cohead_id=cobmisc_cohead_id)
                       AND (cust_id=cohead_cust_id)
                       AND (cust_custtype_id=pCustTypeId)) LOOP

      SELECT createinvoiceConsolidated(_cobmisc.cust_id)
        INTO _tcounter;
      _counter := (_counter + _tcounter);
    END LOOP;
  ELSE
    FOR _cobmisc IN SELECT cobmisc_id
                      FROM cobmisc, cohead, custinfo
                     WHERE((NOT cobmisc_posted)
                       AND (cohead_id=cobmisc_cohead_id)
                       AND (cust_id=cohead_cust_id)
                       AND (cust_custtype_id=pCustTypeId)) LOOP
  
      PERFORM createinvoice(_cobmisc.cobmisc_id);
      _counter := (_counter + 1);

    END LOOP;
  END IF;

  RETURN _counter;
END;

Function: public.createmiscapcheck(integer, integer, date, numeric, integer, integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'createMiscAPCheck() is deprecated - use createCheck() instead';
  RETURN createCheck($1, 'V', $2, $3, pAmount, $5, $6, NULL, $7, $8, FALSE);
END;

Function: public.createmiscapcheck(integer, integer, date, numeric, integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'createMiscAPCheck() is deprecated - use createCheck() instead';
  RETURN createCheck($1, 'V', $2, $3, $4, baseCurrId(), $5, NULL, $6, $7, FALSE);
END;

Function: public.createpkgschema(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pname         ALIAS FOR $1;
  pcomment      ALIAS FOR $2;
  _createtable  TEXT;
  _debug        BOOL    := true;
  _namespaceoid INTEGER := -1;
  _tabs         TEXT[] := ARRAY['cmd',  'cmdarg', 'image',  'metasql',
                                'priv', 'report', 'script', 'uiform'] ;
  _pkgtab       TEXT;

BEGIN
  IF (LENGTH(COALESCE(pname, '')) <= 0) THEN
    RAISE EXCEPTION 'Cannot create a schema for this package without a name.';
  END IF;

  SELECT oid INTO _namespaceoid
  FROM pg_namespace
  WHERE (LOWER(nspname)=LOWER(pname));
  IF (NOT FOUND) THEN
    EXECUTE 'CREATE SCHEMA ' || LOWER(pname);
    EXECUTE 'GRANT ALL ON SCHEMA ' || LOWER(pname) || ' TO GROUP xtrole;';

    SELECT oid INTO _namespaceoid
    FROM pg_namespace
    WHERE (LOWER(nspname)=LOWER(pname));
  END IF;

  FOR i IN ARRAY_LOWER(_tabs,1)..ARRAY_UPPER(_tabs,1) LOOP
    _pkgtab := pname || '.pkg' || _tabs[i];

    IF NOT EXISTS(SELECT oid
                  FROM pg_class
                  WHERE ((relname=_pkgtab)
                     AND (relnamespace=_namespaceoid))) THEN
      _createtable := 'CREATE TABLE ' || _pkgtab || ' () INHERITS (' || _tabs[i] || ');';
      IF (_debug) THEN RAISE NOTICE '%', _createtable; END IF;
      EXECUTE _createtable;

      EXECUTE 'ALTER TABLE ' || _pkgtab ||
              ' ALTER ' || _tabs[i] || '_id SET NOT NULL,' ||
              ' ADD PRIMARY KEY (' || _tabs[i] || '_id),' ||
              ' ALTER ' || _tabs[i] || '_id SET DEFAULT NEXTVAL(''' ||
              _tabs[i] || '_' || _tabs[i] || '_id_seq'');';

      EXECUTE 'REVOKE ALL ON ' || _pkgtab || ' FROM PUBLIC;';
      EXECUTE 'GRANT  ALL ON ' || _pkgtab || ' TO GROUP xtrole;';

      IF (_tabs[i] = 'cmdarg') THEN
        EXECUTE 'ALTER TABLE ' || _pkgtab ||
                ' ADD FOREIGN KEY (cmdarg_cmd_id) REFERENCES ' ||
                pname || '.pkgcmd(cmd_id);';
      END IF;

      EXECUTE 'SELECT dropIfExists(''TRIGGER'', ''pkg' ||
                                   _tabs[i] || 'beforetrigger'', ''' ||
                                   pname || ''');' ;
      EXECUTE 'CREATE TRIGGER pkg' || _tabs[i] || 'beforetrigger ' ||
              'BEFORE INSERT OR UPDATE OR DELETE ON ' || _pkgtab ||
              ' FOR EACH ROW EXECUTE PROCEDURE _pkg' || _tabs[i] || 'beforetrigger();';

      EXECUTE 'SELECT dropIfExists(''TRIGGER'', ''pkg' ||
                                   _tabs[i] || 'altertrigger'', ''' ||
                                   pname || ''');' ;
      EXECUTE 'CREATE TRIGGER pkg' || _tabs[i] || 'altertrigger ' ||
              'BEFORE INSERT OR UPDATE OR DELETE ON ' || _pkgtab ||
              ' FOR EACH ROW EXECUTE PROCEDURE _pkg' || _tabs[i] || 'altertrigger();';

      EXECUTE 'SELECT dropIfExists(''TRIGGER'', ''pkg' ||
                                   _tabs[i] || 'aftertrigger'', ''' ||
                                   pname || ''');' ;
      EXECUTE 'CREATE TRIGGER pkg' || _tabs[i] || 'aftertrigger ' ||
              'AFTER INSERT OR UPDATE OR DELETE ON ' || _pkgtab ||
              ' FOR EACH ROW EXECUTE PROCEDURE _pkg' || _tabs[i] || 'aftertrigger();';

    END IF;
  END LOOP;

  EXECUTE 'COMMENT ON SCHEMA ' || quote_ident(pname) || ' IS ' ||
           quote_literal(pcomment) || ';';

  RETURN _namespaceoid;
END;

Function: public.createpr(bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentType ALIAS FOR $1;
  pParentId ALIAS FOR $2;
  _orderNumber INTEGER;
  _prid INTEGER;

BEGIN

  IF (pParentType = 'W') THEN
    SELECT wo_number INTO _orderNumber
    FROM wo, womatl
    WHERE ((womatl_wo_id=wo_id)
     AND (womatl_id=pParentId));

  ELSIF (pParentType = 'S') THEN
    SELECT CAST(cohead_number AS INTEGER) INTO _orderNumber
    FROM cohead, coitem
    WHERE ((coitem_cohead_id=cohead_id)
     AND (coitem_id=pParentId));

  ELSIF (pParentType = 'F') THEN
    SELECT fetchPrNumber() INTO _orderNumber;

  ELSE
    RETURN -2;
  END IF;

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT createPr(_orderNumber, pParentType, pParentId) INTO _prid;

  RETURN _prid;

END;

Function: public.createpr(integer, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderNumber ALIAS FOR $1;
  pParentType ALIAS FOR $2;
  pParentId ALIAS FOR $3;
  _parent RECORD;
  _prid INTEGER;
  _orderNumber INTEGER;

BEGIN

  IF (pOrderNumber = -1) THEN
    SELECT fetchPrNumber() INTO _orderNumber;
  ELSE
    _orderNumber := pOrderNumber;
  END IF;

  IF (pParentType = 'W') THEN
    SELECT womatl_itemsite_id AS itemsiteid,
           itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq) AS qty,
           womatl_duedate AS duedate, wo_prj_id AS prjid,
           womatl_notes AS notes INTO _parent
    FROM wo, womatl, itemsite
    WHERE ((womatl_wo_id=wo_id)
     AND (womatl_itemsite_id=itemsite_id)
     AND (womatl_id=pParentId));

  ELSIF (pParentType = 'S') THEN
    SELECT coitem_itemsite_id AS itemsiteid,
           (coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) AS qty,
           coitem_scheddate AS duedate, cohead_prj_id AS prjid,
           coitem_memo AS notes INTO _parent
    FROM coitem, cohead
    WHERE ((cohead_id=coitem_cohead_id)
     AND (coitem_id=pParentId));

  ELSIF (pParentType = 'F') THEN
    SELECT planord_itemsite_id AS itemsiteid,
           planord_qty AS qty,
           planord_duedate AS duedate, NULL::INTEGER AS prjid,
           planord_comments AS notes INTO _parent
    FROM planord
    WHERE (planord_id=pParentId);

  ELSE
    RETURN -2;
  END IF;

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT NEXTVAL('pr_pr_id_seq') INTO _prid;
  INSERT INTO pr
  ( pr_id, pr_number, pr_subnumber, pr_status,
    pr_order_type, pr_order_id, pr_prj_id,
    pr_itemsite_id, pr_qtyreq,
    pr_duedate, pr_releasenote )
  VALUES
  ( _prid, _orderNumber, nextPrSubnumber(_orderNumber), 'O',
    pParentType, pParentId, _parent.prjid,
    _parent.itemsiteid, validateOrderQty(_parent.itemsiteid, _parent.qty, TRUE),
    _parent.duedate, _parent.notes );

  RETURN _prid;

END;

Function: public.createpr(integer, bpchar, integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderNumber ALIAS FOR $1;
  pParentType ALIAS FOR $2;
  pParentId ALIAS FOR $3;
  pParentNotes ALIAS FOR $4;
  _parent RECORD;
  _prid INTEGER;
  _orderNumber INTEGER;

BEGIN

  IF (pOrderNumber = -1) THEN
    SELECT fetchPrNumber() INTO _orderNumber;
  ELSE
    _orderNumber := pOrderNumber;
  END IF;

  IF (pParentType = 'W') THEN
    SELECT womatl_itemsite_id AS itemsiteid,
           itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq) AS qty,
           womatl_duedate AS duedate, wo_prj_id AS prjid INTO _parent
    FROM wo, womatl, itemsite
    WHERE ((womatl_wo_id=wo_id)
     AND (womatl_itemsite_id=itemsite_id)
     AND (womatl_id=pParentId));

  ELSIF (pParentType = 'S') THEN
    SELECT coitem_itemsite_id AS itemsiteid,
           (coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) AS qty,
           coitem_scheddate AS duedate, cohead_prj_id AS prjid INTO _parent
    FROM coitem, cohead
    WHERE ((cohead_id=coitem_cohead_id)
     AND (coitem_id=pParentId));

  ELSIF (pParentType = 'F') THEN
    SELECT planord_itemsite_id AS itemsiteid,
           planord_qty AS qty,
           planord_duedate AS duedate, NULL::INTEGER AS prjid 
           INTO _parent
    FROM planord
    WHERE (planord_id=pParentId);

  ELSE
    RETURN -2;
  END IF;

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT NEXTVAL('pr_pr_id_seq') INTO _prid;
  INSERT INTO pr
  ( pr_id, pr_number, pr_subnumber, pr_status,
    pr_order_type, pr_order_id, pr_prj_id,
    pr_itemsite_id, pr_qtyreq, pr_duedate, pr_releasenote )
  VALUES
  ( _prid, _orderNumber, nextPrSubnumber(_orderNumber), 'O',
    pParentType, pParentId, _parent.prjid,
    _parent.itemsiteid, validateOrderQty(_parent.itemsiteid, _parent.qty, TRUE),
    _parent.duedate, pParentNotes );

  RETURN _prid;

END;

Function: public.createpr(integer, integer, numeric, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pQty ALIAS FOR $3;
  pDueDate ALIAS FOR $4;
  pNotes ALIAS FOR $5;
  _prid INTEGER;

BEGIN

  SELECT NEXTVAL('pr_pr_id_seq') INTO _prid;
  INSERT INTO pr
  ( pr_id, pr_number, pr_subnumber, pr_status,
    pr_order_type, pr_order_id,
    pr_itemsite_id, pr_qtyreq, pr_duedate, pr_releasenote )
  VALUES
  ( _prid, pOrderNumber, nextPrSubnumber(pOrderNumber), 'O',
    'M', -1,
    pItemsiteid, pQty, pDuedate, pNotes);

  RETURN _prid;

END;

Function: public.createpr(integer, integer, numeric, date, text, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pQty ALIAS FOR $3;
  pDueDate ALIAS FOR $4;
  pNotes ALIAS FOR $5;
  pOrderType ALIAS FOR $6;
  pOrderId ALIAS FOR $7;
  _prid INTEGER;

BEGIN

  SELECT NEXTVAL('pr_pr_id_seq') INTO _prid;
  INSERT INTO pr
  ( pr_id, pr_number, pr_subnumber, pr_status,
    pr_order_type, pr_order_id,
    pr_itemsite_id, pr_qtyreq, pr_duedate, pr_releasenote )
  VALUES
  ( _prid, pOrderNumber, nextPrSubnumber(pOrderNumber), 'O',
    pOrderType, pOrderId,
    pItemsiteid, pQty, pDuedate, pNotes );

  RETURN _prid;

END;

Function: public.createpriv(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pModule ALIAS FOR $1;
  pName   ALIAS FOR $2;
  pDesc   ALIAS FOR $3;
  _id     INTEGER;
BEGIN

  SELECT priv_id
    INTO _id
    FROM priv
   WHERE(priv_name=pName);

  IF (FOUND) THEN
    UPDATE priv
       SET priv_module=pModule,
           priv_descrip=pDesc
     WHERE(priv_id=_id);
  ELSE
    SELECT nextval('priv_priv_id_seq') INTO _id;
    INSERT INTO priv
          (priv_id, priv_module, priv_name, priv_descrip)
    VALUES(_id, pModule, pName, pDesc);
  END IF;

  RETURN _id;
END;

Function: public.createpurchasetosale(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoitemId ALIAS FOR $1;
  pItemSourceId ALIAS FOR $2;
  pDropShip ALIAS FOR $3;

BEGIN

  RETURN createPurchaseToSale(pCoitemId, pItemSourceId, pDropShip, NULL);

END;

Function: public.createpurchasetosale(integer, integer, boolean, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoitemId ALIAS FOR $1;
  pItemSourceId ALIAS FOR $2;
  pDropShip ALIAS FOR $3;
  pPrice ALIAS FOR $4;

  _s RECORD;
  _w RECORD;
  _i RECORD;
  _shipto RECORD;
  _poheadid INTEGER := -1;
  _poitemid INTEGER := -1;
  _taxtypeid INTEGER := -1;
  _polinenumber INTEGER;
  _ponumber NUMERIC;
  _price NUMERIC;
  _temp INTEGER;

BEGIN

  -- Check for existing poitem for this coitem
  SELECT poitem_id INTO _poitemid
  FROM poitem
  WHERE (poitem_order_id=pCoitemId)
    AND (poitem_order_type='S');
  IF (FOUND) THEN
    RETURN _poitemid;
  END IF;

  SELECT *,
         COALESCE(roundQty(item_fractional, (coitem_qtyord * coitem_qty_invuomratio)), 0.0) AS orderqty
  INTO _s
  FROM cohead JOIN coitem ON (cohead_id = coitem_cohead_id)
    LEFT OUTER JOIN shiptoinfo ON (cohead_shipto_id = shipto_id)
    LEFT OUTER JOIN itemsite ON (coitem_itemsite_id = itemsite_id)
    LEFT OUTER JOIN item ON (item_id = itemsite_item_id)
  WHERE (coitem_id = pCoitemId);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT * INTO _w
  FROM whsinfo JOIN addr ON (warehous_addr_id = addr_id)
    JOIN cntct ON (warehous_cntct_id = cntct_id)
    JOIN itemsite ON (warehous_id = itemsite_warehous_id)
  WHERE (itemsite_id = _s.itemsite_id);

  SELECT * INTO _i
  FROM itemsrc JOIN vendinfo ON (itemsrc_vend_id = vend_id)
    LEFT OUTER JOIN cntct ON (vend_cntct1_id = cntct_id)
    LEFT OUTER JOIN addr ON (vend_addr_id = addr_id)
  WHERE (itemsrc_id = pItemSourceId);
  IF (NOT FOUND) THEN
    RETURN -2;
  END IF;

  SELECT * INTO _shipto
  FROM shiptoinfo JOIN cntct ON (shipto_cntct_id = cntct_id)
    JOIN addr ON (shipto_addr_id = addr_id)
    RIGHT OUTER JOIN cohead ON (cohead_cust_id = shipto_cust_id)
  WHERE (cohead_id = _s.cohead_id)
  LIMIT 1;

  IF (pDropShip) THEN
    SELECT COALESCE(pohead_id, -1) INTO _temp
    FROM pohead
    WHERE ( (COALESCE(pohead_cohead_id, -1) = _s.cohead_id)
      AND (pohead_status = 'U')
      AND (pohead_vend_id = _i.itemsrc_vend_id)
      AND (pohead_shiptoaddress_id = _s.shipto_addr_id) );
  ELSE
    SELECT COALESCE(pohead_id, -1) INTO _temp
    FROM pohead
    WHERE ( (COALESCE(pohead_cohead_id, -1) = _s.cohead_id)
      AND (pohead_status = 'U')
      AND (pohead_vend_id = _i.itemsrc_vend_id)
      AND (pohead_shiptoaddress_id = _w.addr_id) );
  END IF;

  IF (FOUND) THEN
    _poheadid := _temp;
    UPDATE pohead
    SET pohead_dropship = pDropShip
    WHERE (pohead_id = _poheadid);
  ELSE
    SELECT NEXTVAL('pohead_pohead_id_seq') INTO _poheadid;
    SELECT fetchPoNumber() INTO _ponumber;

    IF (pDropShip) THEN
      INSERT INTO pohead
        ( pohead_id, pohead_number, pohead_status, pohead_dropship,
          pohead_agent_username, pohead_vend_id, pohead_taxzone_id,
          pohead_orderdate, pohead_curr_id, pohead_cohead_id,
          pohead_warehous_id, pohead_shipvia,
          pohead_terms_id, pohead_shipto_cntct_id,
          pohead_shipto_cntct_honorific, pohead_shipto_cntct_first_name,
          pohead_shipto_cntct_middle, pohead_shipto_cntct_last_name,
          pohead_shipto_cntct_suffix, pohead_shipto_cntct_phone,
          pohead_shipto_cntct_title, pohead_shipto_cntct_fax, 
          pohead_shipto_cntct_email, pohead_shiptoaddress_id,
          pohead_shiptoaddress1,
          pohead_shiptoaddress2,
          pohead_shiptoaddress3,
          pohead_shiptocity, 
          pohead_shiptostate, pohead_shiptozipcode,
          pohead_shiptocountry, pohead_vend_cntct_id,
          pohead_vend_cntct_honorific, pohead_vend_cntct_first_name,
          pohead_vend_cntct_middle, pohead_vend_cntct_last_name,
          pohead_vend_cntct_suffix, pohead_vend_cntct_phone,
          pohead_vend_cntct_title, pohead_vend_cntct_fax,
          pohead_vend_cntct_email, pohead_vendaddress1,
          pohead_vendaddress2, pohead_vendaddress3,
          pohead_vendcity, pohead_vendstate,
          pohead_vendzipcode, pohead_vendcountry, pohead_comments )
      VALUES
        ( _poheadid, _ponumber, 'U', pDropShip,
          getEffectiveXtUser(), _i.itemsrc_vend_id, _i.vend_taxzone_id,
	  CURRENT_DATE, COALESCE(_i.vend_curr_id, basecurrid()), _s.cohead_id,
          COALESCE(_s.cohead_warehous_id, -1), COALESCE(_i.vend_shipvia, TEXT('')),
          COALESCE(_i.vend_terms_id, -1), COALESCE(_s.cohead_shipto_cntct_id, _shipto.shipto_cntct_id),
          COALESCE(_s.cohead_shipto_cntct_honorific, _shipto.cntct_honorific), COALESCE(_s.cohead_shipto_cntct_first_name, _shipto.cntct_first_name),
          COALESCE(_s.cohead_shipto_cntct_middle, _shipto.cntct_middle), COALESCE(_s.cohead_shipto_cntct_last_name, _shipto.cntct_last_name),
          COALESCE(_s.cohead_shipto_cntct_suffix, _shipto.cntct_suffix), COALESCE(_s.cohead_shipto_cntct_phone, _shipto.cntct_phone),
          COALESCE(_s.cohead_shipto_cntct_title, _shipto.cntct_title), COALESCE(_s.cohead_shipto_cntct_fax, _shipto.cntct_fax),
          COALESCE(_s.cohead_shipto_cntct_email, _shipto.cntct_email), COALESCE(_s.shipto_addr_id, _shipto.addr_id),
          COALESCE(_s.cohead_shiptoaddress1, _shipto.addr_line1),
          COALESCE((_s.cohead_shiptoaddress2 || ' ' || _s.cohead_shiptoaddress3), _shipto.addr_line2),
          COALESCE((_s.cohead_shiptoaddress4 || ' ' || _s.cohead_shiptoaddress5), _shipto.addr_line3),
          COALESCE(_s.cohead_shiptocity, _shipto.addr_city),
          COALESCE(_s.cohead_shiptostate, _shipto.addr_state), COALESCE(_s.cohead_shiptozipcode, _shipto.addr_postalcode),
          COALESCE(_s.cohead_shiptocountry, _shipto.addr_country), _i.cntct_id,
          COALESCE(_i.cntct_honorific, TEXT('')), COALESCE(_i.cntct_first_name, TEXT('')),
          COALESCE(_i.cntct_middle, TEXT('')), COALESCE(_i.cntct_last_name, TEXT('')),
          COALESCE(_i.cntct_suffix, TEXT('')), COALESCE(_i.cntct_phone, TEXT('')),
          COALESCE(_i.cntct_title, TEXT('')), COALESCE(_i.cntct_fax, TEXT('')),
          COALESCE(_i.cntct_email, TEXT('')), COALESCE(_i.addr_line1, TEXT('')),
          COALESCE(_i.addr_line2, TEXT('')), COALESCE(_i.addr_line3, TEXT('')),
          COALESCE(_i.addr_city, TEXT('')), COALESCE(_i.addr_state, TEXT('')),
          COALESCE(_i.addr_postalcode, TEXT('')), COALESCE(_i.addr_country, TEXT('')), COALESCE(_s.cohead_shipcomments, TEXT('')) );
    ELSE
      INSERT INTO pohead
        ( pohead_id, pohead_number, pohead_status, pohead_dropship,
          pohead_agent_username, pohead_vend_id, pohead_taxzone_id,
          pohead_orderdate, pohead_curr_id, pohead_cohead_id,
          pohead_warehous_id, pohead_shipvia,
          pohead_terms_id, pohead_shipto_cntct_id,
          pohead_shipto_cntct_honorific, pohead_shipto_cntct_first_name,
          pohead_shipto_cntct_middle, pohead_shipto_cntct_last_name,
          pohead_shipto_cntct_suffix, pohead_shipto_cntct_phone,
          pohead_shipto_cntct_title, pohead_shipto_cntct_fax, 
          pohead_shipto_cntct_email, pohead_shiptoaddress_id,
          pohead_shiptoaddress1,
          pohead_shiptoaddress2,
          pohead_shiptoaddress3,
          pohead_shiptocity, 
          pohead_shiptostate, pohead_shiptozipcode,
          pohead_shiptocountry, pohead_vend_cntct_id,
          pohead_vend_cntct_honorific, pohead_vend_cntct_first_name,
          pohead_vend_cntct_middle, pohead_vend_cntct_last_name,
          pohead_vend_cntct_suffix, pohead_vend_cntct_phone,
          pohead_vend_cntct_title, pohead_vend_cntct_fax,
          pohead_vend_cntct_email, pohead_vendaddress1,
          pohead_vendaddress2, pohead_vendaddress3,
          pohead_vendcity, pohead_vendstate,
          pohead_vendzipcode, pohead_vendcountry )
      VALUES
        ( _poheadid, _ponumber, 'U', pDropShip,
          getEffectiveXtUser(), _i.itemsrc_vend_id, _i.vend_taxzone_id,
	  CURRENT_DATE, COALESCE(_i.vend_curr_id, basecurrid()), _s.cohead_id,
          COALESCE(_s.cohead_warehous_id, -1), COALESCE(_i.vend_shipvia, TEXT('')),
          COALESCE(_i.vend_terms_id, -1), _w.cntct_id,
          _w.cntct_honorific, _w.cntct_first_name,
          _w.cntct_middle, _w.cntct_last_name,
          _w.cntct_suffix, _w.cntct_phone,
          _w.cntct_title, _w.cntct_fax,
          _w.cntct_email, _w.addr_id,
          _w.addr_line1,
          _w.addr_line2,
          _w.addr_line3,
          _w.addr_city,
          _w.addr_state, _w.addr_postalcode,
          _w.addr_country, _i.cntct_id,
          COALESCE(_i.cntct_honorific, TEXT('')), COALESCE(_i.cntct_first_name, TEXT('')),
          COALESCE(_i.cntct_middle, TEXT('')), COALESCE(_i.cntct_last_name, TEXT('')),
          COALESCE(_i.cntct_suffix, TEXT('')), COALESCE(_i.cntct_phone, TEXT('')),
          COALESCE(_i.cntct_title, TEXT('')), COALESCE(_i.cntct_fax, TEXT('')),
          COALESCE(_i.cntct_email, TEXT('')), COALESCE(_i.addr_line1, TEXT('')),
          COALESCE(_i.addr_line2, TEXT('')), COALESCE(_i.addr_line3, TEXT('')),
          COALESCE(_i.addr_city, TEXT('')), COALESCE(_i.addr_state, TEXT('')),
          COALESCE(_i.addr_postalcode, TEXT('')), COALESCE(_i.addr_country, TEXT('')) );
    END IF;
  END IF;

  SELECT NEXTVAL('poitem_poitem_id_seq') INTO _poitemid;

  SELECT (COALESCE(MAX(poitem_linenumber), 0) + 1) INTO _polinenumber
  FROM poitem
  WHERE (poitem_pohead_id = _poheadid);

  SELECT COALESCE(itemtax_taxtype_id, -1) INTO _taxtypeid
  FROM itemtax
  WHERE (itemtax_item_id = _i.itemsrc_item_id);

  IF (pPrice = NULL) THEN
    SELECT currToCurr(itemsrcp_curr_id, _i.vend_curr_id, itemsrcp_price, CURRENT_DATE) INTO _price
    FROM itemsrcp
    WHERE ( (itemsrcp_itemsrc_id = pItemSourceId)
      AND (itemsrcp_qtybreak <= _s.orderqty) )
    ORDER BY itemsrcp_qtybreak DESC
    LIMIT 1;
  ELSE
    _price := pPrice;
  END IF;

  IF (pDropShip) THEN
    INSERT INTO poitem
      ( poitem_id, poitem_status, poitem_pohead_id, poitem_linenumber, 
        poitem_duedate, poitem_itemsite_id,
        poitem_vend_item_descrip, poitem_vend_uom,
        poitem_invvenduomratio, poitem_qty_ordered, 
        poitem_unitprice, poitem_vend_item_number, 
        poitem_itemsrc_id, poitem_order_id, poitem_order_type, poitem_prj_id, poitem_stdcost, 
        poitem_manuf_name, poitem_manuf_item_number, 
        poitem_manuf_item_descrip, poitem_taxtype_id, poitem_comments )
    VALUES
      ( _poitemid, 'U', _poheadid, _polinenumber,
        _s.coitem_scheddate, _s.coitem_itemsite_id,
        COALESCE(_i.itemsrc_vend_item_descrip, TEXT('')), COALESCE(_i.itemsrc_vend_uom, TEXT('')),
        COALESCE(_i.itemsrc_invvendoruomratio, 1.00), (_s.orderqty / COALESCE(_i.itemsrc_invvendoruomratio, 1.00)),
        _price, COALESCE(_i.itemsrc_vend_item_number, TEXT('')),
        pItemSourceId, pCoitemId, 'S', _s.cohead_prj_id, stdcost(_i.itemsrc_item_id),
        COALESCE(_i.itemsrc_manuf_name, TEXT('')), COALESCE(_i.itemsrc_manuf_item_number, TEXT('')),
        COALESCE(_i.itemsrc_manuf_item_descrip, TEXT('')), _taxtypeid,
        COALESCE(_s.coitem_memo, TEXT('')));
  ELSE
    INSERT INTO poitem
      ( poitem_id, poitem_status, poitem_pohead_id, poitem_linenumber, 
        poitem_duedate, poitem_itemsite_id,
        poitem_vend_item_descrip, poitem_vend_uom,
        poitem_invvenduomratio, poitem_qty_ordered, 
        poitem_unitprice, poitem_vend_item_number, 
        poitem_itemsrc_id, poitem_order_id, poitem_order_type, poitem_prj_id, poitem_stdcost, 
        poitem_manuf_name, poitem_manuf_item_number, 
        poitem_manuf_item_descrip, poitem_taxtype_id )
    VALUES
      ( _poitemid, 'U', _poheadid, _polinenumber,
        _s.coitem_scheddate, _s.coitem_itemsite_id,
        COALESCE(_i.itemsrc_vend_item_descrip, TEXT('')), COALESCE(_i.itemsrc_vend_uom, TEXT('')),
        COALESCE(_i.itemsrc_invvendoruomratio, 1.00), (_s.orderqty / COALESCE(_i.itemsrc_invvendoruomratio, 1.00)),
        _price, COALESCE(_i.itemsrc_vend_item_number, TEXT('')),
        pItemSourceId, pCoitemId, 'S', _s.cohead_prj_id, stdcost(_i.itemsrc_item_id),
        COALESCE(_i.itemsrc_manuf_name, TEXT('')), COALESCE(_i.itemsrc_manuf_item_number, TEXT('')),
        COALESCE(_i.itemsrc_manuf_item_descrip, TEXT('')), _taxtypeid );
  END IF;
  -- Copy characteristics from the coitem to the poitem
  INSERT INTO charass
    ( charass_target_type, charass_target_id, charass_char_id,
      charass_value, charass_default, charass_price )
  SELECT 'PI', _poitemid, charass_char_id,
         charass_value, charass_default, charass_price
  FROM charass
  WHERE ( (charass_target_type='SI')
    AND   (charass_target_id=pCoitemId) );

  UPDATE coitem
  SET coitem_order_type = 'P',
      coitem_order_id = _poitemid
  WHERE ( coitem_id = pCoitemId );

  -- Generate the PoItemCreatedBySo event notice
  INSERT INTO evntlog
              ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id,
                evntlog_number )
  SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id ,
         'P', poitem_id, itemsite_warehous_id,
         (pohead_number || '-' || poitem_linenumber || ': ' || item_number)
  FROM evntnot JOIN evnttype ON (evntnot_evnttype_id=evnttype_id)
       JOIN itemsite ON (evntnot_warehous_id=itemsite_warehous_id)
       JOIN item ON (itemsite_item_id=item_id)
       JOIN poitem ON (poitem_itemsite_id=itemsite_id)
       JOIN pohead ON (poitem_pohead_id=pohead_id)
  WHERE ( (poitem_id=_poitemid)
    AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
    AND (evnttype_name='PoItemCreatedBySo') );

  RETURN _poitemid;

END;

Function: public.createrecurringinvoices()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'createRecurringInvoices() has been deprecated; use createRecurringItems(NULL, ''I'') instead.';

  RETURN createRecurringItems(NULL, 'I');
END;

Function: public.createrecurringitems(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentid  ALIAS FOR $1;      -- if NULL then all items with the given pType
  pType      TEXT := UPPER($2); -- if NULL then all types
                                -- if both are null then all items of all types
  _copystmt  TEXT;
  _count     INTEGER := 0;
  _countstmt TEXT;
  _existcnt  INTEGER;
  _id        INTEGER;
  _interval  TEXT;
  _last      TIMESTAMP WITH TIME ZONE;
  _loopcount INTEGER := 1;
  _maxstmt   TEXT;
  _maxdate   TIMESTAMP WITH TIME ZONE := endOfTime();
  _result    INTEGER := 0;
  _next      TIMESTAMP WITH TIME ZONE;
  _r         RECORD;
  _rt        RECORD;
  _tmp       INTEGER;

BEGIN
  RAISE DEBUG 'createRecurringItems(%, %) entered', pParentid, pType;

  FOR _r IN SELECT *
              FROM recur
             WHERE ((COALESCE(recur_end, endOfTime()) >= CURRENT_TIMESTAMP)
                AND (pParentid IS NULL OR recur_parent_id=pParentid)
                AND (pType IS NULL OR UPPER(recur_parent_type)=UPPER(pType))) LOOP

    RAISE DEBUG 'createRecurringItems looking at recur %, %',
                _r.recur_id, _r.recur_parent_type;
    _r.recur_max := COALESCE(_r.recur_max,
                             CAST(fetchMetricValue('RecurringInvoiceBuffer') AS INTEGER),
                             1);
    _interval := CASE _r.recur_period WHEN 'Y' THEN ' year'
                                      WHEN 'M' THEN ' month'
                                      WHEN 'W' THEN ' week'
                                      WHEN 'D' THEN ' day'
                                      WHEN 'H' THEN ' hour'
                                      WHEN 'm' THEN ' minute'
                                      ELSE NULL
                 END;

    IF (_interval IS NULL OR COALESCE(_r.recur_freq, 0) <= 0) THEN
      RAISE EXCEPTION 'Unknown recurrence frequency % % ON % %',
                      _r.recur_freq,        _r.recur_period,
                      _r.recur_parent_type, _r.recur_parent_id;
    END IF;

    SELECT * INTO _rt FROM recurtype WHERE (UPPER(recurtype_type)=UPPER(pType));
    GET DIAGNOSTICS _count = ROW_COUNT;
    IF (_count <= 0) THEN
      RETURN -10;
    END IF;

    -- if the recurrence type has a max lookahead window, use it
    IF (_r.recur_parent_type = 'I') THEN
      _maxdate := CURRENT_TIMESTAMP + CAST(fetchMetricText('RecurringInvoiceBuffer') || ' days' AS INTERVAL);
    END IF;
    IF (_r.recur_parent_type = 'V') THEN
      _maxdate := CURRENT_TIMESTAMP + CAST(fetchMetricText('RecurringVoucherBuffer') || ' days' AS INTERVAL);
    END IF;
    IF (_maxdate > _r.recur_end) THEN   -- if recur_end is null, _maxdate is ok
      _maxdate = _r.recur_end;
    END IF;

    -- build statements dynamically from the recurtype table because packages
    -- might also require recurring items. this way the algorithm is fixed
    -- and the details are data-driven
    _countstmt := 'SELECT COUNT(*) FROM [fulltable]' 
               || ' WHERE (($1=[table]_recurring_[table]_id)'
               || ' AND NOT([done]) '
               || ' AND ([limit]));';
    _countstmt := REPLACE(_countstmt, '[fulltable]', _rt.recurtype_table);
    _countstmt := REPLACE(_countstmt, '[table]',
                          REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
    _countstmt := REPLACE(_countstmt, '[done]',  _rt.recurtype_donecheck);
    _countstmt := REPLACE(_countstmt, '[limit]',
                          COALESCE(_rt.recurtype_limit, 'TRUE'));

    _maxstmt := 'SELECT MAX([schedcol]) FROM [fulltable]'
               || ' WHERE (($1=[table]_recurring_[table]_id)'
               || '    AND ([limit]));';
    _maxstmt := REPLACE(_maxstmt, '[schedcol]', _rt.recurtype_schedcol);
    _maxstmt := REPLACE(_maxstmt, '[fulltable]',_rt.recurtype_table);
    _maxstmt := REPLACE(_maxstmt, '[table]',
                          REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
    _maxstmt := REPLACE(_maxstmt, '[limit]', COALESCE(_rt.recurtype_limit,
                                                     'TRUE'));

    _copystmt := 'SELECT [copy]($1, [datetime] [more]);';
    _copystmt := REPLACE(_copystmt, '[copy]', _rt.recurtype_copyfunc);
    _copystmt := REPLACE(_copystmt, '[datetime]',
                         CASE WHEN UPPER(_rt.recurtype_copyargs[2])='DATE' THEN
                                    'CAST(''$2'' AS DATE)'
                              ELSE '''$2''' END);
    -- 8.4+:
    -- _copystmt := REPLACE(_copystmt, '[more]',
    --                      REPEAT(', NULL',
    --                             array_length(_rt.recurtype_copyargs) - 2));
    _tmp := CAST(REPLACE(REGEXP_REPLACE(array_dims(_rt.recurtype_copyargs),
                                        '.*:', ''), ']', '') AS INTEGER);
    _copystmt := REPLACE(_copystmt, '[more]', REPEAT(', NULL', _tmp - 2));

    EXECUTE REPLACE(_countstmt, '$1', _r.recur_parent_id::TEXT) INTO _existcnt;
    EXECUTE REPLACE(_maxstmt,   '$1', _r.recur_parent_id::TEXT) INTO _last;
    RAISE DEBUG E'% got %, % got %', _countstmt, _existcnt, _maxstmt, _last;

    _next := _last;
    _loopcount := 1;
    WHILE (_existcnt < _r.recur_max AND _next < _maxdate) LOOP
      _next := _last +
               CAST(_r.recur_freq * _loopcount || _interval AS INTERVAL);
      RAISE DEBUG 'createrecurringitems looping, existcnt = %, max = %, is % between % and %?',
                  _existcnt, _r.recur_max, _next, _r.recur_start, _r.recur_end;

      IF (_next BETWEEN _r.recur_start AND _maxdate) THEN
        RAISE DEBUG 'createrecurringitems executing % with % and %',
                    _copystmt, _r.recur_parent_id, _next;
        -- 8.4+: EXECUTE _copystmt INTO _id USING _r.recur_parent_id, _next;
        EXECUTE REPLACE(REPLACE(_copystmt, '$1', _r.recur_parent_id::TEXT),
                                           '$2', _next::TEXT) INTO _id;
        RAISE DEBUG 'Copying for % returned %', _next, _id;
        _result   := _result   + 1;
        _existcnt := _existcnt + 1;
      END IF;
      _loopcount := _loopcount + 1;
    END LOOP;
  END LOOP;

  RETURN _result;
END;

Function: public.createtodoitem(integer, text, text, text, integer, integer, integer, date, date, bpchar, date, date, integer, text, text)

Returns: integer

Language: PLPGSQL

  
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN createTodoItem($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, NULL);
END;

Function: public.createtodoitem(integer, text, text, text, integer, integer, integer, date, date, bpchar, date, date, integer, text, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoid     ALIAS FOR  $1;
  pusername   ALIAS FOR  $2;
  pname       ALIAS FOR  $3;
  pdesc       ALIAS FOR  $4;
  pincdtid    ALIAS FOR  $5;
  pcrmacctid  ALIAS FOR  $6;
  pOpheadid   ALIAS FOR  $7;
  pstarted    ALIAS FOR  $8;
  pdue        ALIAS FOR  $9;
  pstatus     ALIAS FOR $10;
  passigned   ALIAS FOR $11;
  pcompleted  ALIAS FOR $12;
  ppriority   ALIAS FOR $13;
  pnotes      ALIAS FOR $14;
  powner      ALIAS FOR $15;
  pcntctid    ALIAS FOR $16;

  _todoid     INTEGER;
  _priority   INTEGER         := ppriority;
  _status     CHARACTER(1)    := pstatus;
  _incdtid    INTEGER         := pincdtid;
  _crmacctid  INTEGER         := pcrmacctid;
  _opheadid   INTEGER         := pOpheadid;
  _assigned   DATE            := passigned;
  _result     INTEGER;

BEGIN
  IF (pusername IS NULL OR pusername = '') THEN
    RETURN -1;
  END IF;

  IF (pname IS NULL OR pname = '') THEN
    RETURN -2;
  END IF;

  IF (pdue IS NULL) THEN
    RETURN -3;
  END IF;

  IF (pcompleted IS NOT NULL) THEN
    _status := 'C';
  ELSIF (pstatus IS NULL AND pstarted IS NOT NULL) THEN
    _status := 'I';
  ELSIF (pstatus IS NULL) THEN
    _status := 'N';
  END IF;

  IF (_incdtid <= 0) THEN
    _incdtid := NULL;
  END IF;

  IF (_crmacctid <= 0) THEN
    _crmacctid := NULL;
  END IF;

  IF (_opheadid <= 0) THEN
    _opheadid := NULL;
  END IF;

  IF (_priority <= 0) THEN
    _priority := NULL;
  END IF;

  IF (_assigned IS NULL) THEN
    _assigned := CURRENT_DATE;
  END IF;

  IF (ptodoid IS NULL) THEN
    SELECT NEXTVAL('todoitem_todoitem_id_seq') INTO _todoid;
  ELSE
    _todoid := ptodoid;
  END IF;

  INSERT INTO todoitem ( todoitem_id, todoitem_username, todoitem_name,
                         todoitem_description, todoitem_incdt_id,
                         todoitem_creator_username, todoitem_status,
                         todoitem_active, todoitem_start_date,
                         todoitem_due_date, todoitem_assigned_date,
                         todoitem_completed_date, todoitem_priority_id,
                         todoitem_notes, todoitem_crmacct_id,
                         todoitem_ophead_id, todoitem_owner_username,
                         todoitem_cntct_id
              ) VALUES ( _todoid, pusername, pname,
                         pdesc, _incdtid,
                         getEffectiveXtUser(), _status,
                         TRUE, pstarted,
                         pdue, _assigned,
                         pcompleted, _priority, pnotes, _crmacctid, _opheadid, powner,
                         pcntctid );

  RETURN _todoid;
END;

Function: public.createurl(text, text)

Returns: integer

Language: PLPGSQL

declare
  pTitle ALIAS FOR $1;
  pUrl ALIAS FOR $2;
  _id integer;
begin
  _id := nextval('urlinfo_url_id_seq');
  insert into urlinfo (url_id, url_title, url_url) values (_id, pTitle, pUrl);
  return _id;
end;

Function: public.createuser(pcreateusers text, pusername boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pCreateUsers) THEN
    EXECUTE 'CREATE USER ' || pUsername || ' CREATEROLE   IN GROUP xtrole;';
  ELSE
    EXECUTE 'CREATE USER ' || pUsername || ' NOCREATEROLE IN GROUP xtrole;';
  END IF;
  RETURN 1;
END;

Function: public.createwo(integer, integer, integer, numeric, date, date, text, bpchar, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pStartDate ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;
  pProjectId ALIAS FOR $10;
  _woid INTEGER;
  _result INTEGER;
  _parentType char(1);
  _bomrevid INTEGER;
  _boorevid INTEGER;

BEGIN

  SELECT getActiveRevId('BOM',itemsite_item_id) INTO _bomrevid
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

  SELECT getActiveRevId('BOO',itemsite_item_id) INTO _boorevid
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);
  
  RETURN createWo(pWoNumber, pItemsiteid, pPriority, pQtyOrdered,
                  pStartDate, pDueDate, pProductionNotes,
                  pParentType, pParentId, pProjectId, _bomrevid, _boorevid, NULL);

END;

Function: public.createwo(integer, integer, integer, numeric, date, date, text, bpchar, integer, integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pStartDate ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;
  pProjectId ALIAS FOR $10;
  pBomRevId ALIAS FOR $11;
  pBooRevId ALIAS FOR $12;
BEGIN
  RETURN createWo(pWoNumber, pItemsiteid, pPriority, pQtyOrdered,
                  pStartDate, pDueDate, pProductionNotes,
                  pParentType, pParentId, pProjectId, pBomRevId, pBooRevId, NULL);
END;

Function: public.createwo(integer, integer, integer, numeric, date, date, text, bpchar, integer, integer, integer, integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pStartDate ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;
  pProjectId ALIAS FOR $10;
  pBomRevId ALIAS FOR $11;
  pBooRevId ALIAS FOR $12;
  pCosMethod ALIAS FOR $13;
  _startDate DATE;
  _woid INTEGER;
  _result INTEGER;
  _parentType char(1);
  _parentId INTEGER;
  _cosmethod char(1);
  _itemsite RECORD;
  
BEGIN
  
  _parentType := COALESCE(pParentType, ' ');
  _parentId   := COALESCE(pParentId, -1);

  SELECT * INTO _itemsite FROM itemsite WHERE itemsite_id = pItemsiteid;

--  Check to make sure the itemsite specified is supplied at itemsite
  IF (NOT _itemsite.itemsite_wosupply) THEN
    RETURN -1;
  END IF;

--  Check to make sure if this is a job item that it is tied to a sales order
--  Or if it is just an avarage costed item
  IF (pCosMethod IN ('D', 'P')) THEN
    _cosmethod := pCosMethod;
  ELSE
    IF (_itemsite.itemsite_costmethod = 'J') THEN
      IF (_parentType = ' ' OR _parentId = -1) THEN
        RAISE EXCEPTION 'Work Orders for Item Sites that are Job cost must have a parent order.';
      ELSE
        SELECT COALESCE(itemsite_cosdefault,fetchmetrictext('JobItemCosDefault'),'D') INTO _cosmethod FROM itemsite WHERE itemsite_id=pItemsiteid;
      END IF;
    ELSIF (_itemsite.itemsite_costmethod = 'A') THEN
      _cosmethod := COALESCE(_itemsite.itemsite_cosdefault,fetchmetrictext('JobItemCosDefault'),'D');
    END IF;
  END IF;

--  Check to see if the site calendar metric is set, and if so adjust the start date if necessary
  IF (fetchmetricbool('UseSiteCalendar')) THEN
    _startDate := calculatenextworkingdate(_itemsite.itemsite_warehous_id, pStartDate, 0);
    IF (_startDate != pStartDate) THEN
      _startDate := calculatenextworkingdate(_itemsite.itemsite_warehous_id, pDueDate, -_itemsite.itemsite_leadtime);
    END IF;
  ELSE
    _startDate := pStartDate;
  END IF;
  
--  Grab the next wo_id
  SELECT NEXTVAL('wo_wo_id_seq') INTO _woid;

--  Create the W/O
  INSERT INTO wo
  ( wo_id, wo_number, wo_subnumber, wo_itemsite_id,
    wo_priority, wo_ordtype, wo_ordid,
    wo_status, wo_startdate, wo_duedate,
    wo_qtyord, wo_qtyrcv, wo_prodnotes, wo_prj_id,
    wo_bom_rev_id, wo_boo_rev_id, wo_cosmethod )
  SELECT _woid, pWoNumber, nextWoSubnumber(pWoNumber), itemsite_id,
         pPriority, _parentType, pParentId,
         'O', _startDate, pDueDate,
         roundQty(item_fractional, pQtyOrdered), 0, pProductionNotes, pProjectId, 
         pBomRevid, pBooRevid, _cosmethod
  FROM itemsite, item
  WHERE ((itemsite_item_id=item_id)
   AND (itemsite_id=pItemsiteid));

--  Explode the newly created W/O according to metrics
  IF ( ( SELECT (metric_value='t')
         FROM metric
         WHERE (metric_name='AutoExplodeWO') ) ) THEN
    SELECT explodeWo( _woid, ( SELECT (metric_value = 'M')
                               FROM metric
                               WHERE (metric_name='WOExplosionLevel') ) ) INTO _result;
  ELSE
    _result := _woid;
  END IF;

  RETURN _result;

END;

Function: public.createwo(integer, integer, integer, numeric, integer, date, text, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pLeadTime ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;

BEGIN
  RETURN createWo(pWoNumber, pItemsiteid, pPriority, pQtyOrdered,
                  (pDueDate - pLeadTime), pDueDate, pProductionNotes,
                  pParentType, pParentId, -1);
END;

Function: public.createwo(integer, integer, integer, numeric, integer, date, text, bpchar, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pLeadTime ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;
  pProjectId ALIAS FOR $10;

BEGIN
  RETURN createWo(pWoNumber, pItemsiteid, pPriority, pQtyOrdered,
                  (pDueDate - pLeadTime), pDueDate, pProductionNotes,
                  pParentType, pParentId, pProjectId);
END;

Function: public.createwo(integer, integer, integer, numeric, integer, date, text, bpchar, integer, integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pPriority ALIAS FOR $3;
  pQtyOrdered ALIAS FOR $4;
  pLeadTime ALIAS FOR $5;
  pDueDate ALIAS FOR $6;
  pProductionNotes ALIAS FOR $7;
  pParentType ALIAS FOR $8;
  pParentId ALIAS FOR $9;
  pProjectId ALIAS FOR $10;
  pBomRevId ALIAS FOR $11;
  pBooRevId ALIAS FOR $12;

BEGIN
  RETURN createWo(pWoNumber, pItemsiteid, pPriority, pQtyOrdered,
                  (pDueDate - pLeadTime), pDueDate, pProductionNotes,
                  pParentType, pParentId, pProjectId, pBomRevId, pBooRevId, NULL);
END;

Function: public.createwo(integer, integer, numeric, date, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pQtyOrdered ALIAS FOR $3;
  pStartDate ALIAS FOR $4;
  pDueDate ALIAS FOR $5;
  pProductionNotes ALIAS FOR $6;

BEGIN
  RETURN createWo( pWoNumber, pItemsiteid, 1, pQtyOrdered,
                   pStartDate, pDueDate, pProductionNotes, NULL, NULL, -1);
END;

Function: public.createwo(integer, integer, numeric, integer, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pQtyOrdered ALIAS FOR $3;
  pLeadTime ALIAS FOR $4;
  pDueDate ALIAS FOR $5;
  pProductionNotes ALIAS FOR $6;

BEGIN
  RETURN createWo( pWoNumber, pItemsiteid, 1, pQtyOrdered,
                   (pDueDate - pLeadTime), pDueDate,
                   pProductionNotes, NULL, NULL, -1 ); 
END;

Function: public.createwo(integer, integer, numeric, integer, date, text, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pQtyOrdered ALIAS FOR $3;
  pLeadTime ALIAS FOR $4;
  pDueDate ALIAS FOR $5;
  pProductionNotes ALIAS FOR $6;
  pParentType ALIAS FOR $7;
  pParentId ALIAS FOR $8;

BEGIN
  RETURN createWo( pWoNumber, pItemsiteid, 1, pQtyOrdered,
                   (pDueDate - pLeadTime), pDueDate,
                   pProductionNotes, pParentType, pParentId, -1 ); 
END;

Function: public.createwomaterial(integer, integer, bpchar, integer, numeric, numeric)

Returns: integer

Language: PLPGSQL

DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pUomId ALIAS FOR $4;
  pQtyPer ALIAS FOR $5;
  pScrap ALIAS FOR $6;
  _womatlid INTEGER;

BEGIN

  SELECT createWoMaterial(pWoid,pItemsiteid,pIssueMethod,pUomId,pQtyPer,pScrap,-1, NULL, NULL) INTO _womatlid;

  RETURN _womatlid;
END;

Function: public.createwomaterial(integer, integer, bpchar, integer, numeric, numeric, integer)

Returns: integer

Language: PLPGSQL

DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pUomId ALIAS FOR $4;
  pQtyPer ALIAS FOR $5;
  pScrap ALIAS FOR $6;
  pBomitemId ALIAS FOR $7;
  _womatlid INTEGER;

BEGIN

  _womatlid := (SELECT NEXTVAL('womatl_womatl_id_seq'));

  INSERT INTO womatl
  ( womatl_id, womatl_wo_id, womatl_itemsite_id,
    womatl_issuemethod, womatl_uom_id, womatl_qtyper, womatl_scrap,
    womatl_qtyreq, womatl_qtyiss, womatl_qtywipscrap,
    womatl_wooper_id, womatl_bomitem_id, womatl_duedate )
  SELECT _womatlid, wo_id, pItemsiteid,
         pIssueMethod, pUomId, pQtyPer, pScrap,
         roundQty(item_fractional, (wo_qtyord * (pQtyPer * (1 + pScrap)))), 0, 0,
         -1, pBomitemId, wo_startdate
  FROM wo, itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND (wo_id=pWoid)
   AND (itemsite_id=pItemsiteid) );

  UPDATE wo
  SET wo_adhoc=TRUE
  WHERE (wo_id=pWoid);

  UPDATE wo
  SET wo_status='E'
  WHERE ( (wo_status='O')
   AND (wo_id=pWoid) );

  RETURN _womatlid;
END;

Function: public.createwomaterial(integer, integer, bpchar, integer, numeric, numeric, integer, text, text)

Returns: integer

Language: PLPGSQL

DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pUomId ALIAS FOR $4;
  pQtyPer ALIAS FOR $5;
  pScrap ALIAS FOR $6;
  pBomitemId ALIAS FOR $7;
  pNotes ALIAS FOR $8;
  pRef ALIAS FOR $9;
  _womatlid INTEGER;
  _p RECORD;

BEGIN

  _womatlid := (SELECT NEXTVAL('womatl_womatl_id_seq'));

  INSERT INTO womatl
  ( womatl_id, womatl_wo_id, womatl_itemsite_id,
    womatl_issuemethod, womatl_uom_id, womatl_qtyper, womatl_scrap,
    womatl_qtyreq, womatl_qtyiss, womatl_qtywipscrap,
    womatl_wooper_id, womatl_bomitem_id, womatl_duedate, womatl_notes, womatl_ref )
  SELECT _womatlid, wo_id, pItemsiteid,
         pIssueMethod, pUomId, pQtyPer, pScrap,
         roundQty(item_fractional, (wo_qtyord * (pQtyPer * (1 + pScrap)))), 0, 0,
         -1, pBomitemId, wo_startdate, pNotes, pRef 
  FROM wo, itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND (wo_id=pWoid)
   AND (itemsite_id=pItemsiteid) );

-- Handle all of the Phantom material requirements
  WHILE ( ( SELECT COUNT(*)
            FROM womatl, itemsite, item
            WHERE ( (womatl_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (womatl_wo_id=pWoid)
             AND (item_type='F') ) ) > 0 ) LOOP

    FOR _p IN SELECT wo_qtyord, wo_startdate, womatl_id, womatl_wooper_id
              FROM wo, womatl, itemsite, item
              WHERE ( (womatl_itemsite_id=itemsite_id)
               AND (itemsite_item_id=item_id)
               AND (item_type='F')
               AND (womatl_wo_id=wo_id)
               AND (wo_id=pWoid) ) LOOP

      INSERT INTO womatl
      ( womatl_wo_id, womatl_itemsite_id, womatl_wooper_id,
        womatl_schedatwooper, womatl_duedate,
        womatl_uom_id, womatl_qtyper, womatl_scrap,
        womatl_qtyreq,
        womatl_qtyiss, womatl_qtywipscrap,
        womatl_lastissue, womatl_lastreturn,
        womatl_cost, womatl_picklist, womatl_createwo,
        womatl_issuemethod, womatl_notes, womatl_ref )
      SELECT pWoid, cs.itemsite_id, _p.womatl_wooper_id,
             womatl_schedatwooper, womatl_duedate,
             bomitem_uom_id, (bomitem_qtyper * womatl_qtyper), bomitem_scrap,
             roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id), (_p.wo_qtyord * bomitem_qtyper * womatl_qtyper * (1 + bomitem_scrap))),
             0, 0,
             startOfTime(), startOfTime(),
             0, ci.item_picklist, ( (ci.item_type='M') AND (bomitem_createwo) ),
             bomitem_issuemethod, bomitem_notes, bomitem_ref 
      FROM wo, womatl, bomitem, 
           itemsite AS cs, itemsite AS ps,
           item AS ci, item AS pi
      WHERE ( (womatl_itemsite_id=ps.itemsite_id)
       AND (womatl_wo_id=wo_id)
       AND (bomitem_parent_item_id=pi.item_id)
       AND (bomitem_item_id=ci.item_id)
       AND (ps.itemsite_warehous_id=cs.itemsite_warehous_id)
       AND (cs.itemsite_item_id=ci.item_id)
       AND (ps.itemsite_item_id=pi.item_id)
       AND (woEffectiveDate(_p.wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
       AND (womatl_id=_p.womatl_id));

      DELETE FROM womatl
      WHERE (womatl_id=_p.womatl_id);

    END LOOP;
  END LOOP;

  UPDATE wo
  SET wo_adhoc=TRUE
  WHERE (wo_id=pWoid);

  UPDATE wo
  SET wo_status='E'
  WHERE ( (wo_status='O')
   AND (wo_id=pWoid) );

  RETURN _womatlid;
END;

Function: public.createwomaterial(integer, integer, bpchar, integer, numeric, numeric, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pUomId ALIAS FOR $4;
  pQtyFxd ALIAS FOR $5;
  pQtyPer ALIAS FOR $6;
  pScrap ALIAS FOR $7;
  _womatlid INTEGER;

BEGIN

  SELECT createWoMaterial(pWoid,pItemsiteid,pIssueMethod,pUomId,pQtyFxd,pQtyPer,pScrap,-1, NULL, NULL) INTO _womatlid;

  RETURN _womatlid;
END;

Function: public.createwomaterial(integer, integer, bpchar, integer, numeric, numeric, numeric, integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pUomId ALIAS FOR $4;
  pQtyFxd ALIAS FOR $5;
  pQtyPer ALIAS FOR $6;
  pScrap ALIAS FOR $7;
  pBomitemId ALIAS FOR $8;
  pNotes ALIAS FOR $9;
  pRef ALIAS FOR $10;
  _womatlid INTEGER;
  _p RECORD;

BEGIN

  _womatlid := (SELECT NEXTVAL('womatl_womatl_id_seq'));

  INSERT INTO womatl
  ( womatl_id, womatl_wo_id, womatl_itemsite_id,
    womatl_issuemethod, womatl_uom_id, womatl_qtyfxd, womatl_qtyper, womatl_scrap,
    womatl_qtyreq, womatl_qtyiss, womatl_qtywipscrap,
    womatl_wooper_id, womatl_bomitem_id, womatl_duedate, womatl_notes, womatl_ref )
  SELECT _womatlid, wo_id, pItemsiteid,
         pIssueMethod, pUomId, pQtyFxd, pQtyPer, pScrap,
         roundQty(item_fractional, (pQtyFxd + wo_qtyord * pQtyPer) * (1 + pScrap) ), 0, 0,
         -1, pBomitemId, wo_startdate, pNotes, pRef 
  FROM wo, itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND (wo_id=pWoid)
   AND (itemsite_id=pItemsiteid) );

-- Handle all of the Phantom material requirements
  WHILE ( ( SELECT COUNT(*)
            FROM womatl, itemsite, item
            WHERE ( (womatl_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (womatl_wo_id=pWoid)
             AND (item_type='F') ) ) > 0 ) LOOP

    FOR _p IN SELECT wo_qtyord, wo_startdate, womatl_id, womatl_wooper_id
              FROM wo, womatl, itemsite, item
              WHERE ( (womatl_itemsite_id=itemsite_id)
               AND (itemsite_item_id=item_id)
               AND (item_type='F')
               AND (womatl_wo_id=wo_id)
               AND (wo_id=pWoid) ) LOOP

      INSERT INTO womatl
      ( womatl_wo_id, womatl_itemsite_id, womatl_wooper_id,
        womatl_schedatwooper, womatl_duedate,
        womatl_uom_id, womatl_qtyfxd, womatl_qtyper, womatl_scrap,
        womatl_qtyreq,
        womatl_qtyiss, womatl_qtywipscrap,
        womatl_lastissue, womatl_lastreturn,
        womatl_cost, womatl_picklist, womatl_createwo,
        womatl_issuemethod, womatl_notes, womatl_ref )
      SELECT pWoid, cs.itemsite_id, _p.womatl_wooper_id,
             womatl_schedatwooper, womatl_duedate,
             bomitem_uom_id, bomitem_qtyfxd, (bomitem_qtyper * womatl_qtyper), bomitem_scrap,
             roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id), 
                     ((bomitem_qtyfxd + _p.wo_qtyord * bomitem_qtyper) * womatl_qtyper * (1 + bomitem_scrap))),
             0, 0,
             startOfTime(), startOfTime(),
             0, ci.item_picklist, ( (ci.item_type='M') AND (bomitem_createwo) ),
             bomitem_issuemethod, bomitem_notes, bomitem_ref 
      FROM wo, womatl, bomitem, 
           itemsite AS cs, itemsite AS ps,
           item AS ci, item AS pi
      WHERE ( (womatl_itemsite_id=ps.itemsite_id)
       AND (womatl_wo_id=wo_id)
       AND (bomitem_parent_item_id=pi.item_id)
       AND (bomitem_item_id=ci.item_id)
       AND (ps.itemsite_warehous_id=cs.itemsite_warehous_id)
       AND (cs.itemsite_item_id=ci.item_id)
       AND (ps.itemsite_item_id=pi.item_id)
       AND (woEffectiveDate(_p.wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
       AND (womatl_id=_p.womatl_id));

      DELETE FROM womatl
      WHERE (womatl_id=_p.womatl_id);

    END LOOP;
  END LOOP;

  UPDATE wo
  SET wo_adhoc=TRUE
  WHERE (wo_id=pWoid);

  UPDATE wo
  SET wo_status='E'
  WHERE ( (wo_status='O')
   AND (wo_id=pWoid) );

  RETURN _womatlid;
END;

Function: public.createwomaterial(integer, integer, bpchar, numeric, numeric)

Returns: integer

Language: PLPGSQL

DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pQtyPer ALIAS FOR $4;
  pScrap ALIAS FOR $5;
  _result INTEGER;
BEGIN
  SELECT createWoMaterial(pWoid, pItemsiteid, pIssueMethod, item_inv_uom_id, pQtyPer, pScrap)
    INTO _result
    FROM itemsite JOIN item ON (itemsite_item_id=item_id)
   WHERE(itemsite_id=pItemsiteid);
  RETURN _result;
END;

Function: public.createwomaterial(integer, integer, bpchar, numeric, numeric, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  pIssueMethod ALIAS FOR $3;
  pQtyFxd ALIAS FOR $4;
  pQtyPer ALIAS FOR $5;
  pScrap ALIAS FOR $6;
  _result INTEGER;
BEGIN
  SELECT createWoMaterial(pWoid, pItemsiteid, pIssueMethod, item_inv_uom_id, pQtyFxd, pQtyPer, pScrap)
    INTO _result
    FROM itemsite JOIN item ON (itemsite_item_id=item_id)
   WHERE(itemsite_id=pItemsiteid);
  RETURN _result;
END;

Function: public.creditmemototal(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCreditmemoId ALIAS FOR $1;
  _result       NUMERIC;

BEGIN

  -- TO DO:  Add in line item taxes
  SELECT COALESCE(cmhead_freight,0.0) + COALESCE(cmhead_misc,0.0) +
         ( SELECT COALESCE(ROUND(SUM((cmitem_qtycredit * cmitem_qty_invuomratio) * cmitem_unitprice / cmitem_price_invuomratio), 2), 0.0)
             FROM cmitem
            WHERE (cmitem_cmhead_id=cmhead_id)
           ) +
         (SELECT COALESCE(SUM(tax) * -1, 0) AS tax
           FROM ( SELECT ROUND(SUM(taxdetail_tax),2) AS tax
                  FROM tax
                  JOIN calculateTaxDetailSummary('CM', cmhead_id, 'T') ON (taxdetail_tax_id=tax_id)
                  GROUP BY tax_id) AS data)
           INTO _result
  FROM cmhead
  WHERE (cmhead_id=pCreditmemoId);

  IF (NOT FOUND) THEN
    return 0;
  ELSE
    RETURN _result;
  END IF;

END;

Function: public.crmacct()

Returns: SET OF crmacct

Language: PLPGSQL

A table function that returns CRM Account results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row crmacct%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllCRMAccounts','ViewAllCRMAccounts','MaintainPersonalCRMAccounts','ViewPersonalCRMAccounts')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM crmacct
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM crmacct 
      WHERE crmacct_owner_username = getEffectiveXtUser()
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.crypt(text, text)

Returns: text

Language: C

pg_crypt

Function: public.currconcat(character varying, character varying)

Returns: character varying

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  curr_abbr   ALIAS FOR $1;
  curr_symbol ALIAS FOR $2;
  returnVal   VARCHAR(15) := '';
BEGIN
  IF length(trim(curr_abbr)) > 0 AND length(trim(curr_symbol)) > 0 THEN
      returnVal := trim(curr_abbr) || ' - ' || trim(curr_symbol);

  ELSIF length(trim(curr_abbr)) > 0 THEN
      returnVal := curr_abbr;

  ELSIF length(trim(curr_symbol)) > 0 THEN
      returnVal := curr_symbol;
  END IF;

  RETURN returnVal;
END;

Function: public.currconcat(integer)

Returns: character varying

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  id ALIAS FOR $1;
  returnVal   VARCHAR(15) := '';
BEGIN
  SELECT currConcat(curr_abbr, curr_symbol) INTO returnVal
      FROM curr_symbol WHERE curr_id = id;
  RETURN returnVal;
END;

Function: public.currentapmemonumber()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _number INTEGER;

BEGIN

  SELECT orderseq_number INTO _number
  FROM orderseq
  WHERE (orderseq_name='APMemoNumber');
  IF (NOT FOUND) THEN
    _number := 0;
  END IF;

  RETURN _number;

END;

Function: public.currentarmemonumber()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _number INTEGER;

BEGIN

  SELECT orderseq_number INTO _number
  FROM orderseq
  WHERE (orderseq_name='ARMemoNumber');
  IF (NOT FOUND) THEN
    _number := 0;
  END IF;

  RETURN _number;

END;

Function: public.currentcashrcptnumber()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _number INTEGER;

BEGIN

  SELECT orderseq_number INTO _number
  FROM orderseq
  WHERE (orderseq_name='CashRcptNumber');
  IF (NOT FOUND) THEN
    _number := 0;
  END IF;

  RETURN _number;

END;

Function: public.currentnumber(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pName   ALIAS FOR $1;
  _number INTEGER;

BEGIN
  SELECT orderseq_number INTO _number
  FROM orderseq
  WHERE (orderseq_name=pName);
  IF (NOT FOUND) THEN
    _number := 0;
  END IF;

  RETURN _number;

END;

Function: public.currexchangecheckoverlap()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    numberOfOverlaps INTEGER NOT NULL := 0;
    curr_string VARCHAR(16);
    new_id INTEGER;
BEGIN
  new_id := NEW.curr_id;
  -- ensure that effective date <= expiration date
  IF NEW.curr_effective > NEW.curr_expires THEN
    RAISE EXCEPTION
      'Effective date % must be earlier than expiration date %',
      NEW.curr_effective, NEW.curr_expires;
  END IF;

  -- ensure new exchange rate does not overlap in time with any others
  SELECT count(*) INTO numberOfOverlaps
    FROM curr_rate
    WHERE curr_id = NEW.curr_id
      AND curr_rate_id != NEW.curr_rate_id
      AND (
          (curr_effective BETWEEN
              NEW.curr_effective AND NEW.curr_expires OR
           curr_expires BETWEEN
              NEW.curr_effective AND NEW.curr_expires)
         OR (curr_effective <= NEW.curr_effective AND
             curr_expires   >= NEW.curr_expires)
      );
  IF numberOfOverlaps > 0 THEN
    SELECT currConcat(curr_symbol, curr_abbr)
      INTO curr_string
      FROM curr_symbol
      WHERE curr_id = new_id;
    RAISE EXCEPTION
      'The date range % to % overlaps with another date range.',
      NEW.curr_effective, NEW.curr_expires;
  END IF;
  RETURN NEW;
END;

Function: public.currgain(integer, numeric, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pId ALIAS FOR $1;
  pValue ALIAS FOR $2;
  pStart ALIAS FOR $3;
  pEnd ALIAS FOR $4;
  _start DATE;
  _end DATE;
  _gain NUMERIC;
  _multiplier	INTEGER	:= 1;

BEGIN
  IF (pEnd = pStart OR pValue = 0) THEN
    RETURN 0;
  END IF;

  IF (pStart > pEnd) THEN
    _start := pEnd;
    _end   := pStart;
    _multiplier := -1;
  ELSE
    _start := pStart;
    _end := pEnd;
  END IF;

  _gain := currToBase(pId, pValue, _start) - currToBase(pId, pValue, _end);
  IF (_gain IS NULL) THEN
    RAISE EXCEPTION 'Missing exchange rate for curr_id % on % or %',
                    pId, _start, _end;
  END IF;

  RETURN _gain * _multiplier;
END;

Function: public.curronebase()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  baseCount INTEGER := 0;
BEGIN
  IF NEW.curr_base = TRUE THEN
    SELECT count(*)
      INTO baseCount
      FROM curr_symbol
      WHERE curr_base = TRUE
        AND curr_id != NEW.curr_id;
    IF baseCount > 0 THEN
      RAISE EXCEPTION
          'Cannot make % - % the base currency because one is already defined.',
          NEW.curr_symbol, NEW.curr_abbr;
    ELSE
      SELECT count(*)
        INTO baseCount
        FROM curr_rate
        WHERE curr_id = NEW.curr_id;
      IF baseCount = 0 THEN
        -- put a row in the curr_rate table to avoid special-case
        -- code for converting base currency to base currency
        INSERT INTO curr_rate
          (curr_id, curr_rate, curr_effective, curr_expires) VALUES
          (NEW.curr_id, 1, startOfTime(), endOfTime());
      END IF;
    END IF;
  END IF;
  RETURN NEW;
END;

Function: public.currrate(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCurrId ALIAS FOR $1;
  pDate   ALIAS FOR $2;
  _returnVal NUMERIC;
BEGIN
  SELECT curr_rate INTO _returnVal
  FROM curr_rate
  WHERE ( (curr_id=pCurrId)
  AND (pDate BETWEEN curr_effective AND curr_expires) );

  IF (FOUND) THEN
    RETURN _returnVal;
  ELSE
    RAISE EXCEPTION 'Currency exchange rate not found on %',formatDate(pDate);
  END IF;

END;

Function: public.currtobase(integer, numeric, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pId     ALIAS FOR $1;
  pValue  ALIAS FOR $2;
  _date  DATE;
  _output NUMERIC;
BEGIN
  _date := $3;
  IF _date IS NULL THEN
    _date := 'now';
  END IF;

  IF pValue = 0 OR pValue IS NULL THEN
    _output := 0;
  ELSIF (baseCurrId() = pId) THEN
    _output := pValue;
  ELSE
    SELECT pValue / curr_rate
        INTO  _output
      FROM  curr_rate
     WHERE curr_id = pId
       AND _date BETWEEN curr_effective AND curr_expires;
    IF (_output IS NULL OR NOT FOUND) THEN
      RAISE EXCEPTION 'No exchange rate for % on %', pId, _date;
    END IF;
  END IF;
  RETURN _output;
END;

Function: public.currtocurr(integer, integer, numeric, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFromCurr ALIAS FOR $1;
  pToCurr ALIAS FOR $2;
  pValue   ALIAS FOR $3;
  pEffective ALIAS FOR $4;
  _convertedValue NUMERIC;
  _fromRate NUMERIC;
  _toRate NUMERIC;
BEGIN
  IF pFromCurr = pToCurr THEN
    RETURN pValue;
  END IF;

  IF pValue = 0 OR pValue IS NULL THEN
    RETURN 0;
  END IF;

  SELECT curr_rate INTO _fromRate
  FROM curr_rate
  WHERE curr_id = pFromCurr
    AND pEffective BETWEEN curr_effective AND curr_expires;

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'No exchange rate for % on %', pFromCurr, pEffective;
  END IF;

  SELECT curr_rate INTO _toRate
  FROM curr_rate
  WHERE curr_id = pToCurr
    AND pEffective BETWEEN curr_effective AND curr_expires;

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'No exchange rate for % on %', pToCurr, pEffective;
  END IF;

  _convertedValue := pValue * _toRate / _fromRate;

  RETURN _convertedValue;
END;

Function: public.currtolocal(integer, numeric, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pId     ALIAS FOR $1;
    pValue  ALIAS FOR $2;
    _date   DATE;
    _output NUMERIC;
BEGIN
    _date := $3;
    IF _date IS NULL THEN
        _date := 'now';
    END IF;

    IF pValue = 0 OR pValue IS NULL THEN
        _output := 0;
    ELSIF (baseCurrId() = pId) THEN
      _output := pValue;
    ELSE
        SELECT pValue * curr_rate
            INTO  _output
            FROM  curr_rate
            WHERE curr_id = pId
              AND _date BETWEEN curr_effective AND curr_expires;
        IF (_output IS NULL OR NOT FOUND) THEN
          RAISE EXCEPTION 'No exchange rate for % on %', pId, _date;
        END IF;
    END IF;
    RETURN _output;
END;

Function: public.custitem(asof integer, shipto_id integer, cust_id date)

Returns: SET OF integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.

  -- Non Exclusive
  SELECT item_id
  FROM item 
  WHERE (NOT item_exclusive)
   AND (item_sold)
  UNION
  -- Exclusive, Shipto match
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_item_id=item_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND ($2 != -1)
   AND (ipsass_shipto_id=$2)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_prodcat_id=item_prodcat_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND ($2 != -1)
   AND (ipsass_shipto_id=$2)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
   -- Exclusive, Shipto pattern match
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_item_id=item_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN shiptoinfo ON (shipto_num ~ ipsass_shipto_pattern)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (COALESCE(length(ipsass_shipto_pattern), 0) > 0)
   AND (ipsass_cust_id=$1)
   AND ($2 != -1)
   AND (shipto_id=$2)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_prodcat_id=item_prodcat_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN shiptoinfo ON (shipto_num ~ ipsass_shipto_pattern)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (COALESCE(length(ipsass_shipto_pattern), 0) > 0)
   AND (ipsass_cust_id=$1)
   AND ($2 != -1)
   AND (shipto_id=$2)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
   -- Exclusive, Customer match
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_item_id=item_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (ipsass_cust_id=$1)
   AND (ipsass_shipto_id=-1)
   AND (ipsass_shipto_pattern='')
   AND (ipsass_custtype_id=-1)
   AND (ipsass_custtype_pattern='')
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_prodcat_id=item_prodcat_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (ipsass_cust_id=$1)
   AND (ipsass_shipto_id=-1)
   AND (ipsass_shipto_pattern='')
   AND (ipsass_custtype_id=-1)
   AND (ipsass_custtype_pattern='')
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  -- Exclusive, Customer Type match
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_item_id=item_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN custinfo ON (ipsass_custtype_id=cust_custtype_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (cust_id=$1)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_prodcat_id=item_prodcat_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN custinfo ON (ipsass_custtype_id=cust_custtype_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (cust_id=$1)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  -- Exclusive, Customer Type pattern match
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_item_id=item_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN custtype ON (custtype_code ~ ipsass_custtype_pattern)
    JOIN custinfo ON (cust_custtype_id=custtype_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (COALESCE(length(ipsass_custtype_pattern), 0) > 0)
   AND (cust_id=$1)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
  UNION
  SELECT item_id
  FROM item
    JOIN ipsiteminfo ON (ipsitem_prodcat_id=item_prodcat_id)
    JOIN ipshead ON (ipshead_id=ipsitem_ipshead_id)
    JOIN ipsass ON (ipsass_ipshead_id=ipshead_id)
    JOIN custtype ON (custtype_code ~ ipsass_custtype_pattern)
    JOIN custinfo ON (cust_custtype_id=custtype_id)
  WHERE (item_exclusive)
   AND (item_sold)
   AND (COALESCE(length(ipsass_custtype_pattern), 0) > 0)
   AND (cust_id=$1)
   AND ($3 BETWEEN ipshead_effective AND (ipshead_expires - 1))
   

Function: public.customercanpurchase(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pitemid ALIAS FOR $1;
  pCustid ALIAS FOR $2;

BEGIN
  RETURN customerCanPurchase(pitemid, pCustid, -1);
END;

Function: public.customercanpurchase(integer, integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pitemid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  pShiptoid AlIAS FOR $3;
  _id INTEGER;
  _item RECORD;

BEGIN
  RETURN customerCanPurchase(pitemid, pCustid, pShiptoid, CURRENT_DATE);
END;

Function: public.customercanpurchase(integer, integer, integer, date)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pitemid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  pShiptoid AlIAS FOR $3;
  pAsOf ALIAS FOR $4;
  _id INTEGER;
  _item RECORD;

BEGIN

  SELECT item_sold, item_exclusive
    INTO _item
    FROM item
   WHERE(item_id=pItemid);

--  Make sure that this is at least a sold Item
  IF (NOT _item.item_sold) THEN
    RETURN FALSE;
  END IF;

--  Everyone can purchase a non-exclusive item
  IF (NOT _item.item_exclusive) THEN
    RETURN TRUE;
  END IF;

  IF(pShiptoid != -1) THEN
--  Check for a shipto Assigned Price
    SELECT ipsitem_id INTO _id
      FROM ipsiteminfo, ipshead, ipsass
     WHERE((ipsitem_ipshead_id=ipshead_id)
       AND (ipsass_ipshead_id=ipshead_id)
       AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
       AND (ipsitem_item_id=pItemid)
       AND (ipsass_shipto_id != -1)
       AND (ipsass_shipto_id=pShiptoid))
     LIMIT 1;
    IF (FOUND) THEN
      RETURN TRUE;
    END IF;
    SELECT ipsitem_id INTO _id
      FROM ipsiteminfo, item, ipshead, ipsass
     WHERE((ipsitem_ipshead_id=ipshead_id)
       AND (ipsitem_prodcat_id = item_prodcat_id)
       AND (ipsass_ipshead_id=ipshead_id)
       AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
       AND (item_id=pItemid)
       AND (ipsass_shipto_id != -1)
       AND (ipsass_shipto_id=pShiptoid))
     LIMIT 1;
    IF (FOUND) THEN
      RETURN TRUE;
    END IF;

--  Check for a Shipto Pattern Assigned Price
    SELECT ipsitem_id INTO _id
      FROM ipsiteminfo, ipshead, ipsass, shiptoinfo
     WHERE((ipsitem_ipshead_id=ipshead_id)
       AND (ipsass_ipshead_id=ipshead_id)
       AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
       AND (COALESCE(length(ipsass_shipto_pattern), 0) > 0)
       AND (shipto_num ~ ipsass_shipto_pattern)
       AND (ipsass_cust_id=pCustid)
       AND (ipsitem_item_id=pItemid)
       AND (shipto_id=pShiptoid))
     LIMIT 1;
    IF (FOUND) THEN
      RETURN TRUE;
    END IF;
    SELECT ipsitem_id INTO _id
      FROM ipsiteminfo, item, ipshead, ipsass, shiptoinfo
     WHERE((ipsitem_ipshead_id=ipshead_id)
       AND (ipsitem_prodcat_id = item_prodcat_id)
       AND (ipsass_ipshead_id=ipshead_id)
       AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
       AND (COALESCE(length(ipsass_shipto_pattern), 0) > 0)
       AND (shipto_num ~ ipsass_shipto_pattern)
       AND (ipsass_cust_id=pCustid)
       AND (item_id=pItemid)
       AND (shipto_id=pShiptoid))
     LIMIT 1;
    IF (FOUND) THEN
      RETURN TRUE;
    END IF;
  END IF;

--  Check for a Customer Assigned Price
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, ipshead, ipsass
   WHERE((ipsitem_ipshead_id=ipshead_id)
     AND (ipsass_ipshead_id=ipshead_id)
     AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND (ipsitem_item_id=pItemid)
     AND (COALESCE(length(ipsass_shipto_pattern), 0) = 0)
     AND (ipsass_cust_id=pCustid))
   LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, item, ipshead, ipsass
   WHERE((ipsitem_ipshead_id=ipshead_id)
     AND (ipsitem_prodcat_id = item_prodcat_id)
     AND (ipsass_ipshead_id=ipshead_id)
     AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND (item_id=pItemid)
     AND (COALESCE(length(ipsass_shipto_pattern), 0) = 0)
     AND (ipsass_cust_id=pCustid))
   LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;

--  Check for a Customer Type Assigned Price
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, ipshead, ipsass, custinfo
   WHERE( (ipsitem_ipshead_id=ipshead_id)
     AND  (ipsass_ipshead_id=ipshead_id)
     AND  (ipsass_custtype_id != -1)
     AND  (cust_custtype_id = ipsass_custtype_id)
     AND  (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND  (ipsitem_item_id=pItemid)
     AND  (cust_id=pCustid))
    LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, item, ipshead, ipsass, custinfo
   WHERE( (ipsitem_ipshead_id=ipshead_id)
     AND  (ipsitem_prodcat_id = item_prodcat_id)
     AND  (ipsass_ipshead_id=ipshead_id)
     AND  (ipsass_custtype_id != -1)
     AND  (cust_custtype_id = ipsass_custtype_id)
     AND  (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND  (item_id=pItemid)
     AND  (cust_id=pCustid))
    LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;

--  Check for a Customer Type Pattern Assigned Price
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, ipshead, ipsass, custtype, custinfo
   WHERE((ipsitem_ipshead_id=ipshead_id)
     AND (ipsass_ipshead_id=ipshead_id)
     AND (coalesce(length(ipsass_custtype_pattern), 0) > 0)
     AND (custtype_code ~ ipsass_custtype_pattern)
     AND (cust_custtype_id=custtype_id)
     AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND (ipsitem_item_id=pItemid)
     AND (cust_id=pCustid))
   LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;
  SELECT ipsitem_id INTO _id
    FROM ipsiteminfo, item, ipshead, ipsass, custtype, custinfo
   WHERE((ipsitem_ipshead_id=ipshead_id)
     AND (ipsitem_prodcat_id = item_prodcat_id)
     AND (ipsass_ipshead_id=ipshead_id)
     AND (coalesce(length(ipsass_custtype_pattern), 0) > 0)
     AND (custtype_code ~ ipsass_custtype_pattern)
     AND (cust_custtype_id=custtype_id)
     AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
     AND (item_id=pItemid)
     AND (cust_id=pCustid))
   LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;

--  That's it, Sales don't count - yet
  RETURN FALSE;

END;

Function: public.dearmor(text)

Returns: bytea

Language: C

pg_dearmor

Function: public.decrypt(bytea, bytea, text)

Returns: bytea

Language: C

pg_decrypt

Function: public.decrypt_iv(bytea, bytea, bytea, text)

Returns: bytea

Language: C

pg_decrypt_iv

Function: public.defaultlocationname(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _p RECORD;

BEGIN

  SELECT itemsite_location_id, itemsite_location INTO _p
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

  IF (NOT FOUND) THEN
    RETURN 'Error';
  ELSIF (_p.itemsite_location_id = -1) THEN
    RETURN _p.itemsite_location;
  ELSE
    RETURN formatLocationName(_p.itemsite_location_id);
  END IF;

END;

Function: public.deleteaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if the passed accnt is used in a Cost Category
  SELECT costcat_id INTO _check
  FROM costcat
  WHERE ( (costcat_asset_accnt_id=pAccntid)
     OR   (costcat_liability_accnt_id=pAccntid)
     OR   (costcat_adjustment_accnt_id=pAccntid)
     OR   (costcat_purchprice_accnt_id=pAccntid)
     OR   (costcat_laboroverhead_accnt_id=pAccntid)
     OR   (costcat_scrap_accnt_id=pAccntid)
     OR   (costcat_invcost_accnt_id=pAccntid)
     OR   (costcat_wip_accnt_id=pAccntid)
     OR   (costcat_shipasset_accnt_id=pAccntid)
     OR   (costcat_mfgscrap_accnt_id=pAccntid)
     OR   (costcat_transform_accnt_id=pAccntid)
     OR   (costcat_freight_accnt_id=pAccntid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Check to see if the passed accnt is used in a Sales Account Assignment
  SELECT salesaccnt_id INTO _check
  FROM salesaccnt
  WHERE ( (salesaccnt_sales_accnt_id=pAccntid)
     OR   (salesaccnt_credit_accnt_id=pAccntid)
     OR   (salesaccnt_cos_accnt_id=pAccntid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to see if the passed accnt is used in a A/R Account Assignment
  SELECT araccnt_id INTO _check
  FROM araccnt
  WHERE ( (araccnt_freight_accnt_id=pAccntid)
     OR   (araccnt_ar_accnt_id=pAccntid)
     OR   (araccnt_prepaid_accnt_id=pAccntid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to see if the passed accnt is used in a Warehouse
  IF EXISTS (SELECT 1
               FROM whsinfo
              WHERE (warehous_default_accnt_id=pAccntid)) THEN
    RETURN -4;
  END IF;

--  Check to see if the passed accnt is used in a Bank Account
  SELECT bankaccnt_id INTO _check
  FROM bankaccnt
  WHERE (bankaccnt_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

--  Check to see if the passed accnt is used in an Expense Category
  SELECT expcat_id INTO _check
  FROM expcat
  WHERE ( (expcat_exp_accnt_id=pAccntid)
     OR   (expcat_liability_accnt_id=pAccntid)
     OR   (expcat_purchprice_accnt_id=pAccntid)
     OR   (expcat_freight_accnt_id=pAccntid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -6;
  END IF;

--  Check to see if the passed accnt is used in a Tax Code
  SELECT tax_id INTO _check
  FROM tax
  WHERE (tax_sales_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -7;
  END IF;

--  Check to see if the passed accnt is used in a Standard Journal Item
  SELECT stdjrnlitem_id INTO _check
  FROM stdjrnlitem
  WHERE (stdjrnlitem_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -8;
  END IF;

--  Check to see if the passed accnt is used in a A/P Account Assignment
  SELECT apaccnt_ap_accnt_id INTO _check
  FROM apaccnt
  WHERE ( (apaccnt_ap_accnt_id=pAccntid)
     OR   (apaccnt_prepaid_accnt_id=pAccntid)
     OR   (apaccnt_discount_accnt_id=pAccntid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -9;
  END IF;

--  Check to see if the passed accnt is used in an A/R Open Item record
  SELECT aropen_accnt_id INTO _check
    FROM aropen
   WHERE (aropen_accnt_id=pAccntid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -11;
  END IF;

--  Check to see if the passed accnt has been used in the G/L
  SELECT gltrans_accnt_id INTO _check
  FROM gltrans
  WHERE (gltrans_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -99;
  END IF;

  SELECT glseries_accnt_id INTO _check
  FROM glseries
  WHERE (glseries_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -99;
  END IF;

  SELECT trialbal_accnt_id INTO _check
  FROM trialbal
  WHERE (trialbal_accnt_id=pAccntid)
    AND (trialbal_beginning != 0 OR trialbal_ending != 0)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -99;
  END IF;

  SELECT cashrcptmisc_accnt_id INTO _check
  FROM cashrcptmisc
  WHERE (cashrcptmisc_accnt_id=pAccntid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -99;
  END IF;

--  Delete any non-critical use
  DELETE FROM flitem
  WHERE (flitem_accnt_id=pAccntid);

  -- only possible because of trialbal error-check above
  DELETE FROM trialbal
  WHERE (trialbal_accnt_id=pAccntid)
    AND (trialbal_beginning=0)
    AND (trialbal_ending=0);

--  Delete the Account
  DELETE FROM accnt
  WHERE (accnt_id=pAccntid);

  RETURN 0;

END;

Function: public.deleteaccountingperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  _check RECORD;

BEGIN

--  Check to make sure that the passed period is not closed
  IF ( ( SELECT period_closed
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

--  Check to make sure that there are not any posted G/L Transactions
--  in the period.
  SELECT gltrans_id INTO _check
  FROM gltrans, period
  WHERE ( (gltrans_date BETWEEN period_start AND period_end)
   AND (gltrans_posted)
   AND (period_id=pPeriodid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  SELECT b.period_id INTO _check
    FROM period AS a, period AS b
   WHERE((a.period_id=pPeriodid)
     AND (a.period_end < b.period_start))
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

--  Delete the period
  DELETE FROM period
  WHERE (period_id=pPeriodid);

  RETURN 1;

END;

Function: public.deleteaccountingyearperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  _check RECORD;

BEGIN

--  Check to make sure that the passed yearperiod is not closed
  IF ( ( SELECT yearperiod_closed
         FROM yearperiod
         WHERE (yearperiod_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

  -- this yearperiod is in use by existing periods
  IF (EXISTS(SELECT period_id
             FROM period
             WHERE (period_yearperiod_id=pPeriodid))) THEN
    RETURN -2;
  END IF;

--  Delete the yearperiod
  DELETE FROM yearperiod
  WHERE (yearperiod_id=pPeriodid);

  RETURN 1;

END;

Function: public.deleteaddress(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  paddrId     ALIAS FOR $1;
  _count      INTEGER := 0;
BEGIN
  SELECT count(*) INTO _count
    FROM cntct
    WHERE (cntct_active
      AND  (cntct_addr_id = paddrId));
  IF (_count > 0) THEN
    RETURN -1;
  END IF;

  SELECT count(*) INTO _count
    FROM vendinfo
    WHERE (vend_active
      AND  (vend_addr_id = paddrId));
  IF (_count > 0) THEN
    RETURN -2;
  END IF;

  SELECT count(*) INTO _count
    FROM shiptoinfo
    WHERE (shipto_active
      AND  (shipto_addr_id = paddrId));
  IF (_count > 0) THEN
    RETURN -3;
  END IF;

  SELECT count(*) INTO _count
    FROM vendaddrinfo
    WHERE (vendaddr_addr_id = paddrId);
  IF (_count > 0) THEN
    RETURN -4;
  END IF;

  SELECT count(*) INTO _count
    FROM whsinfo
    WHERE (warehous_active
      AND  (warehous_addr_id = paddrId));
  IF (_count > 0) THEN
    RETURN -5;
  END IF;

  UPDATE cntct SET cntct_addr_id = NULL WHERE (cntct_addr_id = paddrId);
  UPDATE vendinfo SET vend_addr_id = NULL WHERE (vend_addr_id = paddrId);
  UPDATE shiptoinfo SET shipto_addr_id = NULL WHERE (shipto_addr_id =paddrId);
  UPDATE vendaddrinfo SET vendaddr_addr_id = NULL
    WHERE (vendaddr_addr_id = paddrId);
  UPDATE whsinfo SET warehous_addr_id = NULL WHERE (warehous_addr_id=paddrId);

  DELETE FROM addr WHERE addr_id = paddrId;
  RETURN 0;
END;

Function: public.deleteapcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'deleteAPCheck() is deprecated - use deleteCheck() instead';
  RETURN deleteCheck($1);
END;

Function: public.deletebankadjustmenttype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankadjtypeid ALIAS FOR $1;
  _check INTEGER;

BEGIN

-- Check to see if the the adjustment type is being used in any adjustments
  SELECT bankadj_bankadjtype_id INTO _check
    FROM bankadj
   WHERE (bankadj_bankadjtype_id=pBankadjtypeid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the Account
  DELETE FROM bankadjtype
  WHERE (bankadjtype_id=pbankadjtypeid);

  RETURN 0;

END;

Function: public.deletebankreconciliation(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pbankrecid    ALIAS FOR $1;
BEGIN
  DELETE FROM bankrecitem
  WHERE bankrecitem_bankrec_id=pbankrecid;

  DELETE FROM bankrec
  WHERE bankrec_id=pbankrecid;

  RETURN 0;
END;

Function: public.deletebom(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _result INTEGER;

BEGIN

  IF (fetchmetricbool('RevControl')) THEN
    SELECT rev_id INTO _result
    FROM rev
    WHERE ((rev_target_id=pItemid)
    AND (rev_target_type = 'BOM'))
    LIMIT 1;
    IF (FOUND) THEN
      RAISE EXCEPTION 'Bill of Materials has revision control records and may not be deleted.';
    END IF;
  END IF;

  DELETE FROM bomhead
  WHERE (bomhead_item_id=pItemid);
  DELETE FROM bomitem
  WHERE (bomitem_parent_item_id=pItemid);

  RETURN 0;

END;

Function: public.deletebomworkset(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWorksetid ALIAS FOR $1;

BEGIN

--  All done with the bomwork set indicated by pWorksetid, delete all of it
  DELETE FROM bomwork
  WHERE (bomwork_set_id=pWorksetid);

  RETURN 1;

END;

Function: public.deletebudget(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBudgheadid ALIAS FOR $1;

BEGIN
  DELETE FROM budgitem WHERE (budgitem_budghead_id=pBudgheadid);
  DELETE FROM budghead WHERE (budghead_id=pBudgheadid);

  RETURN pBudgheadid;
END;

Function: public.deletebudgetitems(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBudgheadid ALIAS FOR $1;

BEGIN
  DELETE FROM budgitem WHERE (budgitem_budghead_id=pBudgheadid);

  RETURN pBudgheadid;
END;

Function: public.deletecashrcpt(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcashrcptid ALIAS FOR $1;
  _ccreceipt    BOOLEAN;

BEGIN

  IF EXISTS(SELECT cashrcpt_id
            FROM cashrcpt
            JOIN ccpay ON (cashrcpt_cust_id=ccpay_cust_id)
                       AND ((CASE WHEN TRIM(COALESCE(cashrcpt_docnumber, ''))='' THEN TEXT(cashrcpt_id)
                                  ELSE cashrcpt_docnumber
                             END)=ccpay_order_number)
            WHERE ((cashrcpt_fundstype IN ('A', 'D', 'M', 'V'))
               AND (ccpay_status NOT IN ('D', 'X'))
               AND (ccpay_id NOT IN (SELECT payco_ccpay_id FROM payco))
               AND (cashrcpt_id=pcashrcptid))) THEN
    RETURN -1;
  END IF;

  IF EXISTS(SELECT cashrcpt_id
            FROM cashrcpt
            WHERE ( (cashrcpt_id=pcashrcptid)
              AND   (cashrcpt_posted) )) THEN
    RETURN -2;
  END IF;

  -- If there are applications for this Cash Receipt then
  -- it has been posted and reversed.  Void instead of delete.
  IF EXISTS(SELECT cashrcpt_id
            FROM cashrcpt JOIN cashrcptitem ON (cashrcptitem_cashrcpt_id=cashrcpt_id)
                          JOIN arapply ON ((arapply_reftype='CRA') AND
                                           (arapply_ref_id=cashrcptitem_id))
            WHERE (cashrcpt_id=pcashrcptid))
     OR
     EXISTS(SELECT cashrcpt_id
            FROM cashrcpt JOIN cashrcptmisc ON (cashrcptmisc_cashrcpt_id=cashrcpt_id)
                          JOIN arapply ON ((arapply_reftype='CRD') AND
                                           (arapply_ref_id=cashrcptmisc_id))
            WHERE (cashrcpt_id=pcashrcptid)) THEN
    UPDATE cashrcpt SET cashrcpt_void = TRUE
    WHERE (cashrcpt_id=pcashrcptid);
    RETURN 1;
  END IF;

  DELETE FROM cashrcptitem
  WHERE (cashrcptitem_cashrcpt_id=pcashrcptid);

  DELETE FROM cashrcptmisc
  WHERE (cashrcptmisc_cashrcpt_id=pcashrcptid);

  DELETE FROM cashrcpt
  WHERE (cashrcpt_id=pcashrcptid);

  RETURN 1;

END;

Function: public.deletecharacteristic(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCharid ALIAS FOR $1;
  _check INTEGER;
  _r RECORD;

BEGIN

--  Cache the specifics of the characteristic
  SELECT * INTO _r
  FROM char
  WHERE (char_id=pCharid);
  IF (NOT(FOUND)) THEN
    RETURN 0;
  END IF;

--  If the passed characteristic is used
  SELECT * INTO _r
  FROM charass
  WHERE (charass_char_id=pCharid)
  LIMIT 1;
  IF (FOUND) THEN
    IF (_r.charass_target_type = 'I') THEN
      RETURN -1;
    ELSIF (_r.charass_target_type = 'C') THEN
      RETURN -2;
    ELSIF (_r.charass_target_type = 'ADDR') THEN
      RETURN -3;
    ELSIF (_r.charass_target_type = 'CNTCT') THEN
      RETURN -4;
    ELSIF (_r.charass_target_type = 'CRMACCT') THEN
      RETURN -5;
    ELSIF (_r.charass_target_type = 'INCDT	') THEN
      RETURN -6;
    ELSIF (_r.charass_target_type = 'EMP') THEN
      RETURN -7;
    ELSE
      RETURN -99;
    END IF;
  END IF;

--  Delete the passed characterisitic
  DELETE FROM char
  WHERE (char_id=pCharid);

  RETURN pCharid;

END;

Function: public.deletecheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid ALIAS FOR $1;

BEGIN
  IF (SELECT (NOT checkhead_void) OR checkhead_posted OR checkhead_replaced
              OR checkhead_deleted
              OR (checkhead_ach_batch IS NOT NULL AND checkhead_printed)
      FROM checkhead
      WHERE (checkhead_id=pCheckid) ) THEN
    RETURN -1;
  END IF;

  UPDATE checkhead
  SET checkhead_deleted=TRUE
  WHERE (checkhead_id=pCheckid);

  RETURN 1;

END;

Function: public.deleteclasscode(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClasscodeid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if any items are assigned to the passed classcode
  SELECT item_id INTO _check
  FROM item
  WHERE (item_classcode_id=pClasscodeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the passed classcode
  DELETE FROM classcode
  WHERE (classcode_id=pClasscodeid);

  RETURN pClasscodeid;

END;

Function: public.deletecompany(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcompanyid ALIAS FOR $1;

BEGIN
  IF (EXISTS(SELECT accnt_id
             FROM accnt, company
             WHERE ((accnt_company=company_number)
               AND  (company_id=pcompanyid))
            )) THEN
    RETURN -1;
  END IF;

  DELETE FROM company
  WHERE (company_id=pcompanyid);

  RETURN pcompanyid;

END;

Function: public.deletecreditmemo(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;

BEGIN

  DELETE FROM cmitem
  WHERE (cmitem_cmhead_id=pCmheadid);

  DELETE FROM cmhead
  WHERE (cmhead_id=pCmheadid);

  RETURN TRUE;

END;

Function: public.deletecustomer(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;

BEGIN

  PERFORM shipto_id
  FROM shiptoinfo
  WHERE (shipto_cust_id=pCustid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  PERFORM cohead_id
  FROM cohead
  WHERE (cohead_cust_id=pCustid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  PERFORM cmhead_id
  FROM cmhead
  WHERE (cmhead_cust_id=pCustid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  PERFORM cohist_id
  FROM cohist
  WHERE (cohist_cust_id=pCustid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  PERFORM aropen_id
  FROM aropen
  WHERE (aropen_cust_id=pCustid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

  PERFORM checkhead_recip_id
    FROM checkhead
   WHERE ((checkhead_recip_id=pCustid)
     AND  (checkhead_recip_type='C'))
   LIMIT 1;
   IF (FOUND) THEN
     RETURN -6;
   END IF;

  PERFORM invchead_id
     FROM invchead
    WHERE(invchead_cust_id=pCustid)
    LIMIT 1;
  IF (FOUND) THEN
    RETURN -7;
  END IF;

  PERFORM quhead_id
     FROM quhead
    WHERE(quhead_cust_id=pCustid)
    LIMIT 1;
  IF (FOUND) THEN
    RETURN -8;
  END IF;

  DELETE FROM taxreg
   WHERE ((taxreg_rel_type='C')
     AND  (taxreg_rel_id=pCustid));

  DELETE FROM ipsass
  WHERE (ipsass_cust_id=pCustid);

  DELETE FROM custinfo
  WHERE (cust_id=pCustid);

  UPDATE crmacct SET crmacct_cust_id = NULL
  WHERE (crmacct_cust_id=pCustid);

  RETURN 0;

END;

Function: public.deletecustomertype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCusttypeid ALIAS FOR $1;

BEGIN

  IF EXISTS(SELECT 1
              FROM custinfo
             WHERE (cust_custtype_id=pCusttypeid)) THEN
    RETURN -1;
  END IF;

  DELETE FROM ipsass
  WHERE (ipsass_custtype_id=pCusttypeid);

  DELETE FROM salesaccnt
  WHERE (salesaccnt_custtype_id=pCusttypeid);

  DELETE FROM araccnt
  WHERE (araccnt_custtype_id=pCusttypeid);

  DELETE FROM custform
  WHERE (custform_custtype_id=pCusttypeid);

  DELETE FROM custtype
  WHERE (custtype_id=pCusttypeid);

  RETURN pCusttypeid;

END;

Function: public.deleteempgrp(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pempgrpid ALIAS FOR $1;

BEGIN
--  Check to see if any employees are assigned to the passed empgrp
  PERFORM empgrpitem_emp_id
  FROM empgrpitem
  WHERE (empgrpitem_empgrp_id=pempgrpid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  DELETE FROM empgrp     WHERE (empgrp_id=pempgrpid);

  RETURN 0;
END;

Function: public.deleteexpiredips()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;

BEGIN

  FOR _r IN SELECT ipshead_id
    FROM ipshead
    WHERE (ipshead_expires <= current_date)
  LOOP

    DELETE FROM ipsass
      WHERE (ipsass_ipshead_id=_r.ipshead_id);
    DELETE FROM ipsiteminfo
      WHERE (ipsitem_ipshead_id=_r.ipshead_id);
    DELETE FROM ipsfreight
      WHERE (ipsfreight_ipshead_id=_r.ipshead_id);
    DELETE FROM ipshead
      WHERE (ipshead_id=_r.ipshead_id);
  END LOOP;

  RETURN TRUE;

END;

Function: public.deletefile(integer)

Returns: boolean

Language: PLPGSQL

declare
  pId ALIAS FOR $1;
begin
  delete from file
  where ( file_id in (
    select file_id
    from file
      join docass on (docass_target_id=file_id)
                 and (docass_target_type='FILE')
    where ( docass_id = pId ) ) );

  delete from docass where docass_id = pId;

  return true;
end;

Function: public.deleteflgrp(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlgrpid ALIAS FOR $1;
  _r RECORD;

BEGIN

  FOR _r IN SELECT flgrp_id
            FROM flgrp
            WHERE (flgrp_flgrp_id=pFlgrpid) LOOP
    PERFORM deleteFlgrp(_r.flgrp_id);
  END LOOP;

  DELETE FROM flitem
  WHERE (flitem_flgrp_id=pFlgrpid);

  DELETE FROM flspec
  WHERE (flspec_flgrp_id=pFlgrpid);

  DELETE FROM flgrp
  WHERE (flgrp_id=pFlgrpid);

  RETURN 1;

END;

Function: public.deleteform(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFormid ALIAS FOR $1;
  _key TEXT;
  _check INTEGER;

BEGIN

--  Cache the key of the passed form
  SELECT form_key INTO _key
  FROM form
  WHERE (form_id=pFormid);
  IF (NOT(FOUND)) THEN
    RETURN 0;
  END IF;

--  Handle checks based on the type of the form
  IF (_key='Chck') THEN
    SELECT bankaccnt_id INTO _check
    FROM bankaccnt
    WHERE (bankaccnt_check_form_id=pFormid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -1;
    END IF;

  END IF;

--  Delete the form
  DELETE FROM form
  WHERE (form_id=pFormid);

  RETURN pFormid;

END;

Function: public.deletefreightclass(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFreightClassid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if any items are assigned to the passed freightclass
  SELECT item_id INTO _check
  FROM item
  WHERE (item_freightclass_id=pFreightClassid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the passed freightclass
  DELETE FROM freightclass
  WHERE (freightclass_id=pFreightClassid);

  RETURN pFreightClassid;

END;

Function: public.deleteglseries(integer)

Returns: integer

Language: PLPGSQL

DECLARE
  pSequence ALIAS FOR $1;

BEGIN

  DELETE FROM glseries
  WHERE (glseries_sequence=pSequence);

  RETURN pSequence;

END;

Function: public.deleteglseries(integer, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pNotes ALIAS FOR $2;
  _trialbalid INTEGER;
  _count INTEGER;
  _r RECORD;

BEGIN

--  March through all of the G/L Transactions for the passed sequence
  FOR _r IN SELECT gltrans_id, gltrans_date, gltrans_accnt_id, gltrans_amount, gltrans_posted, gltrans_rec,
                   accnt_forwardupdate, period_id, period_closed, period_freeze
            FROM accnt, gltrans LEFT OUTER JOIN period ON (gltrans_date BETWEEN period_start AND period_end)
            WHERE ( (gltrans_accnt_id=accnt_id)
             AND (NOT gltrans_deleted)
             AND (gltrans_sequence=pSequence) ) LOOP

--  If we can post into a Trial Balance, do so
    IF ( (NOT _r.period_closed) AND 
       ( (NOT _r.period_freeze) OR (checkPrivilege('PostFrozenPeriod')) ) AND
       (  NOT _r.gltrans_rec) AND
       ( _r.gltrans_posted ) ) THEN

--  Try to find an existing trialbal
      SELECT trialbal_id INTO _trialbalid
      FROM trialbal
      WHERE ( (trialbal_period_id=_r.period_id)
       AND (trialbal_accnt_id=_r.gltrans_accnt_id) );

      GET DIAGNOSTICS _count = ROW_COUNT;
      IF (_count > 0) THEN

--  We found a trialbal, update it with the G/L Transaction
--  Note - two stage update to avoid any funny value caching logic
        IF (_r.gltrans_amount > 0) THEN
          UPDATE trialbal
          SET trialbal_credits = (trialbal_credits - _r.gltrans_amount)
          WHERE (trialbal_id=_trialbalid);
        ELSE
          UPDATE trialbal
          SET trialbal_debits = (trialbal_debits - (_r.gltrans_amount * -1))
          WHERE (trialbal_id=_trialbalid);
        END IF;

        UPDATE trialbal
        SET trialbal_ending = (trialbal_beginning - trialbal_debits + trialbal_credits),
            trialbal_dirty=TRUE
        WHERE (trialbal_id=_trialbalid);

      ELSE
        RAISE EXCEPTION 'Can not delete G/L Series.  Trial balance record not found.';
      END IF;

--  Forward update if we should
      IF (_r.accnt_forwardupdate AND fetchmetricbool('ManualForwardUpdate')) THEN
        PERFORM forwardUpdateTrialBalance(_trialbalid);
      END IF;

--  Delete any bank reconciliation records if this was marked cleared but non reconciled
    DELETE FROM bankrecitem
    WHERE ((bankrecitem_source='GL')
    AND (bankrecitem_source_id=_r.gltrans_id));

--  Unflag any journals as posted as a result of this series
    UPDATE sltrans SET
      sltrans_posted=false,
      sltrans_gltrans_journalnumber=null
    FROM gltrans
    WHERE ((gltrans_sequence=pSequence)
    AND (sltrans_gltrans_journalnumber=gltrans_journalnumber));
    
--  Mark the G/L Transaction as deleted
      UPDATE gltrans SET
        gltrans_posted=false,
        gltrans_deleted=true,
        gltrans_notes=gltrans_notes || E'\n' || pNotes
      WHERE (gltrans_id=_r.gltrans_id);

    ELSIF (_r.period_freeze) THEN
        RAISE EXCEPTION 'Can not delete a G/L Transaction in a frozen period';
    ELSIF (_r.period_closed) THEN
        RAISE EXCEPTION 'Can not delete a G/L Transaction on account % in a closed period', formatGlAccount(_r.gltrans_accnt_id);
    ELSIF (_r.gltrans_rec) THEN
        RAISE EXCEPTION 'Can not delete a G/L Transaction that has been reconciled';
    ELSIF (NOT _r.gltrans_posted) THEN
        RAISE EXCEPTION 'Can not delete a G/L Transaction that has not been posted to Trial Balance';
    END IF;

  END LOOP;

  RETURN true;

END;

Function: public.deleteincident(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pincdtid    ALIAS FOR $1;
  _count      INTEGER := 0;
  _incdtnbr   INTEGER := 0;
BEGIN
  SELECT COUNT(*) INTO _count
  FROM todoitem
  WHERE (todoitem_incdt_id=pincdtid);
  IF (_count > 0) THEN
    RETURN -1;
  END IF;

  DELETE FROM comment
   WHERE((comment_source='INCDT')
     AND (comment_source_id=pincdtid));

  DELETE FROM incdthist
   WHERE (incdthist_incdt_id=pincdtid);

  DELETE FROM imageass
  WHERE ((imageass_source='INCDT')
     AND (imageass_source_id=pincdtid));

  DELETE FROM url
  WHERE ((url_source='INCDT')
     AND (url_source_id=pincdtid));

  SELECT incdt_number INTO _incdtnbr
  FROM incdt
  WHERE (incdt_id=pincdtid);

  DELETE FROM incdt
    WHERE (incdt_id=pincdtid);

-- Incident #11538 needs to be fully resolved before release can be implemented
--    PERFORM releaseIncidentNumber(_incdtnbr);

  RETURN 0;
END;

Function: public.deleteinvoice(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;

BEGIN
  UPDATE shipitem SET shipitem_invoiced=FALSE, shipitem_invcitem_id=NULL
  FROM invcitem
  WHERE ((shipitem_invoiced)
    AND  (shipitem_invcitem_id=invcitem_id)
    AND  (invcitem_invchead_id=pInvcheadid));

  UPDATE coitem SET coitem_status = 'O'
  WHERE ((coitem_status = 'C')
    AND  (coitem_id IN (SELECT cobill_coitem_id
		        FROM cobill, invcitem
			WHERE ((cobill_invcitem_id=invcitem_id)
			  AND  (invcitem_invchead_id=pInvcheadid)))));

  UPDATE cobill SET cobill_invcnum=NULL, cobill_invcitem_id=NULL
  FROM invcitem
  WHERE ((cobill_invcitem_id=invcitem_id)
    AND  (invcitem_invchead_id=pInvcheadid));

  UPDATE invdetail SET invdetail_invcitem_id=NULL
  FROM invcitem
  WHERE ((invdetail_invcitem_id=invcitem_id)
    AND  (invcitem_invchead_id=pInvcheadid));

  UPDATE cobmisc SET cobmisc_invcnumber=NULL, cobmisc_invchead_id=NULL,
		     cobmisc_posted=FALSE
  WHERE (cobmisc_invchead_id=pInvcheadid);

  DELETE FROM aropenalloc
  WHERE (aropenalloc_doctype='I')
    AND (aropenalloc_doc_id=pInvcheadid);

  DELETE FROM invcitem
  WHERE (invcitem_invchead_id=pInvcheadid);

  DELETE FROM invchead
  WHERE (invchead_id=pInvcheadid);

  RETURN pInvcheadid;

END;

Function: public.deleteipsitem(pipsitemid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  DELETE FROM ipsiteminfo WHERE ipsitem_id=pIpsItemId;

  RETURN 1;
END;

Function: public.deleteipsprodcat(pipsitemid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN

  DELETE FROM ipsiteminfo WHERE ipsitem_id=pIpsItemId;
  
  RETURN 1;
END;

Function: public.deleteitem(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _result INTEGER;

BEGIN

  SELECT bomitem_id INTO _result
  FROM bomitem
  WHERE (bomitem_item_id=pItemid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  SELECT itemsite_id INTO _result
  FROM itemsite
  WHERE (itemsite_item_id=pItemid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  SELECT itemsub_id INTO _result
  FROM itemsub
  WHERE (itemsub_sub_item_id=pItemid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  IF (fetchmetricbool('RevControl')) THEN
    SELECT rev_id INTO _result
    FROM rev
    WHERE ((rev_target_id=pItemid)
    AND (rev_target_type = 'BOM'))
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -6;
    END IF;
  END IF;

  DELETE FROM bomhead
  WHERE (bomhead_item_id=pItemid);
  DELETE FROM bomitem
  WHERE (bomitem_item_id=pItemid);

  DELETE FROM itemcost
  WHERE (itemcost_item_id=pItemid);
  DELETE FROM costhist
  WHERE (costhist_item_id=pItemid);

  DELETE FROM itemsub
  WHERE (itemsub_parent_item_id=pItemid);
  DELETE FROM itemsub
  WHERE (itemsub_sub_item_id=pItemid);

  DELETE FROM itemsrcp
  WHERE (itemsrcp_itemsrc_id IN (SELECT itemsrc_id FROM itemsrc WHERE (itemsrc_item_id=pItemid)));
  DELETE FROM itemsrc
  WHERE (itemsrc_item_id=pItemid);

  DELETE FROM itemalias
  WHERE (itemalias_item_id=pItemid);

  DELETE FROM itemgrpitem
  WHERE (itemgrpitem_item_id=pItemid);

  DELETE FROM ipsiteminfo
  WHERE (ipsitem_item_id=pItemid);

  DELETE FROM imageass
  WHERE ( (imageass_source='I')
    AND   (imageass_source_id=pItemid) );

  DELETE FROM locitem
  WHERE (locitem_item_id=pItemid);

  DELETE FROM itemtax
   WHERE(itemtax_item_id=pItemid);

  DELETE FROM itemsite
  WHERE (itemsite_item_id=pItemid);

  DELETE FROM itemuom
   WHERE(itemuom_itemuomconv_id IN (SELECT itemuomconv_id
                                      FROM itemuomconv
                                     WHERE(itemuomconv_item_id=pItemid)));

  DELETE FROM itemuomconv
   WHERE(itemuomconv_item_id=pItemid);

  DELETE FROM item
  WHERE (item_id=pItemid);

  RETURN 0;

END;

Function: public.deleteitemcost(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemId ALIAS FOR $1;
  pCostElemId ALIAS FOR $2;
  _itemcost_id INTEGER;
  _postcost_return BOOLEAN;
  _std_cost NUMERIC;

BEGIN
  SELECT itemcost_id INTO _itemcost_id
  FROM itemcost
  WHERE ( (itemcost_item_id = pItemId) AND (itemcost_costelem_id = pCostElemId) );

  IF (NOT FOUND) THEN
	RAISE EXCEPTION 'itemcost % not found for. ', pItemId || ' & ' || pCostElemId;
  END IF;

  SELECT itemcost_stdcost INTO _std_cost
  FROM itemcost
  WHERE (itemcost_id = _itemcost_id);

  IF (_std_cost > 0) THEN
--Actual Cost is updated to zero to ensure inventory is valued correctly
    SELECT updateCost(_itemcost_id, 0);
  END IF;

  DELETE FROM itemcost
  WHERE (itemcost_id=_itemcost_id);
 
  RETURN _itemcost_id;	

END;

Function: public.deleteitemsite(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _result INTEGER;
  _lotserial BOOLEAN;
  _bbom BOOLEAN;
  _mfg BOOLEAN;
  _standard BOOLEAN;

BEGIN

  IF ( ( SELECT ( (itemsite_qtyonhand <> 0) OR (itemsite_nnqoh <> 0) )
         FROM itemsite
         WHERE (itemsite_id=pItemsiteid) ) ) THEN
    RETURN -9;
  END IF;

  SELECT metric_value='t' INTO _bbom
    FROM metric
   WHERE (metric_name='BBOM');

  SELECT metric_value='t' INTO _lotserial
    FROM metric
   WHERE (metric_name='LotSerialControl');

  SELECT metric_value NOT IN ('PostBooks', 'Standard') INTO _mfg
    FROM metric
   WHERE (metric_name='Application');

  SELECT metric_value='Standard' INTO _standard
    FROM metric
   WHERE (metric_name='Application');

  SELECT invhist_id INTO _result
  FROM invhist
  WHERE (invhist_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  IF (_lotserial) THEN
    SELECT lsdetail_id INTO _result
    FROM lsdetail
    WHERE (lsdetail_itemsite_id=pItemsiteid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -1;
    END IF;
  END IF;

  SELECT wo_id INTO _result
  FROM wo
  WHERE (wo_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  SELECT womatl_id INTO _result
  FROM womatl
  WHERE (womatl_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  SELECT womatlvar_id INTO _result
  FROM womatlvar
  WHERE ( (womatlvar_parent_itemsite_id=pItemsiteid)
   OR (womatlvar_component_itemsite_id=pItemsiteid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  IF (_bbom) THEN
    SELECT brdvar_id INTO _result
    FROM xtmfg.brdvar
    WHERE ( (brdvar_itemsite_id=pItemsiteid)
     OR (brdvar_parent_itemsite_id=pItemsiteid) )
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -2;
    END IF;
  END IF;

  SELECT coitem_id INTO _result
  FROM coitem
  WHERE (coitem_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  SELECT cohist_id INTO _result
  FROM cohist
  WHERE (cohist_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  SELECT quitem_id INTO _result
  FROM quitem
  WHERE (quitem_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  SELECT cmitem_id INTO _result
  FROM cmitem
  WHERE (cmitem_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;


  SELECT poitem_id INTO _result
  FROM poitem
  WHERE (poitem_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  SELECT recv_id INTO _result
  FROM recv
  WHERE (recv_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  SELECT poreject_id INTO _result
  FROM poreject
  WHERE (poreject_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  SELECT pr_id INTO _result
  FROM pr
  WHERE (pr_itemsite_id=pItemsiteid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  IF (_mfg OR _standard) THEN
    SELECT planord_id INTO _result
    FROM planord
    WHERE (planord_itemsite_id=pItemsiteid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -5;
    END IF;
  END IF;

  IF (_mfg) THEN
    SELECT pschitem_id INTO _result
    FROM xtmfg.pschitem
    WHERE (pschitem_itemsite_id=pItemsiteid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -6;
    END IF;

    SELECT woopervar_id INTO _result
    FROM xtmfg.woopervar
    WHERE (woopervar_parent_itemsite_id=pItemsiteid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -2;
    END IF;
    
  END IF;

  IF (_mfg OR _standard) THEN
    SELECT itemsite_id INTO _result
    FROM itemsite
    WHERE (itemsite_supply_itemsite_id=pItemsiteid)
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -7;
    END IF;
  END IF;

  DELETE FROM invcnt
  WHERE (invcnt_itemsite_id=pItemsiteid);

  DELETE FROM itemloc
  WHERE (itemloc_itemsite_id=pItemsiteid);
  DELETE FROM itemlocdist
  WHERE (itemlocdist_itemsite_id=pItemsiteid);

  IF (_bbom) THEN
    DELETE FROM xtmfg.brddist
    WHERE (brddist_itemsite_id=pItemsiteid);
  END IF;

  DELETE FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

  RETURN 0;

END;

Function: public.deleteitemuom(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemuomid ALIAS FOR $1;

BEGIN
  DELETE FROM itemuom WHERE itemuom_id=pItemuomid;

  RETURN 0;
END;

Function: public.deleteitemuomconv(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemuomconvid ALIAS FOR $1;
  _fromuomid     INTEGER;
  _invuomid      INTEGER;
  _itemid        INTEGER;
  _touomid       INTEGER;

BEGIN
  SELECT itemuomconv_item_id, item_inv_uom_id,
         itemuomconv_from_uom_id, itemuomconv_to_uom_id
          INTO _itemid, _invuomid, _fromuomid, _touomid
  FROM itemuomconv JOIN item ON (itemuomconv_item_id=item_id)
  WHERE (itemuomconv_id=pItemuomconvid);

  IF EXISTS(SELECT *
            FROM uomusedforitem(_itemid)
            WHERE ((uom_id IN (_fromuomid, _touomid))
               AND (uom_id != _invuomid)) ) THEN
    RETURN -1;
  END IF;

  DELETE FROM itemuom WHERE itemuom_itemuomconv_id=pItemuomconvid;
  DELETE FROM itemuomconv WHERE itemuomconv_id=pItemuomconvid;

  RETURN 0;
END;

Function: public.deletelocation(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if any itemsite used the passed location as their default
  SELECT itemsite_id INTO _check
  FROM itemsite
  WHERE (itemsite_location_id=pLocationid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Check to see if any inventory is currently stored at the passed location
  SELECT itemloc_id INTO _check
  FROM itemloc
  WHERE (itemloc_location_id=pLocationid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to see if any undistributed inventory transactions are currently posted at the passed location
  SELECT itemlocdist_id INTO _check
  FROM itemlocdist
  WHERE ( (itemlocdist_source_type='L')
  AND (itemlocdist_source_id=pLocationid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to see if the passed location has any Inventory Detail posted against it
  SELECT invdetail_id INTO _check
  FROM invdetail
  WHERE (invdetail_location_id=pLocationid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

--  Delete any associated locitem records
  DELETE FROM locitem
  WHERE (locitem_location_id=pLocationid);

--  Delete the location record
  DELETE FROM location
  WHERE (location_id=pLocationid);

  RETURN pLocationid;

END;

Function: public.deletemetasql(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pid ALIAS FOR $1;
BEGIN
  DELETE FROM metasql WHERE metasql_id = pid;
  RETURN 0;
END;

Function: public.deleteopenrecurringitems(integer, text, timestamp with time zone, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentid     ALIAS FOR $1;
  pType         TEXT                     := UPPER($2);
  pDatetime     TIMESTAMP WITH TIME ZONE := COALESCE($3, startOfTime());
  pInclParent   BOOLEAN                  := COALESCE($4, FALSE);

  _count         INTEGER := 0;
  _delchildstmt  TEXT;
  _delparentstmt TEXT;
  _rt            RECORD;
  _tmp           INTEGER;
BEGIN
  RAISE DEBUG 'deleteOpenRecurringItems(%, %, %)', pParentid, pType, pDatetime;

  IF (pParentid IS NULL) THEN
    RETURN -11;
  END IF;

  SELECT * INTO _rt FROM recurtype WHERE (UPPER(recurtype_type)=pType);
  GET DIAGNOSTICS _count = ROW_COUNT;
  IF (_count <= 0) THEN
    RETURN -10;
  END IF;

  -- 2 deletes avoid reparenting problems if the parent gets deleted first
  IF (_rt.recurtype_delfunc IS NULL) THEN
    _delchildstmt := 'DELETE FROM [fulltable] '
                  || ' WHERE (NOT ([done])'
                  || '    AND ([schedcol]>''$2'')'
                  || '    AND ([table]_recurring_[table]_id=$1)'
                  || '    AND ([table]_id!=$1));';

    _delparentstmt := 'DELETE FROM [fulltable] USING recur'
                   || ' WHERE (NOT ([done])'
                   || '    AND ([schedcol]>''$2'')'
                   || '    AND ([table]_recurring_[table]_id=$1)'
                   || '    AND ([table]_id=$1));';

  ELSE
    _delchildstmt := 'SELECT [delfunc]([table]_id)'
                  || '  FROM [fulltable] '
                  || ' WHERE (NOT ([done])'
                  || '    AND ([schedcol]>''$2'')'
                  || '    AND ([table]_recurring_[table]_id=$1)'
                  || '    AND ([table]_id!=$1));';
    _delparentstmt := 'SELECT [delfunc]([table]_id)'
                   || '  FROM [fulltable] '
                   || ' WHERE (NOT ([done])'
                   || '    AND ([schedcol]>''$2'')'
                   || '    AND ([table]_recurring_[table]_id=$1)'
                   || '    AND ([table]_id!=$1));';
    _delchildstmt  := REPLACE(_delchildstmt,  '[delfunc]', _rt.recurtype_delfunc);
    _delparentstmt := REPLACE(_delparentstmt, '[delfunc]', _rt.recurtype_delfunc);
  END IF;

  RAISE DEBUG '_delchildstmt has been set to %', _delchildstmt;

  _delchildstmt := REPLACE(_delchildstmt, '[fulltable]', _rt.recurtype_table);
  _delchildstmt := REPLACE(_delchildstmt, '[table]',
                            REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
  _delchildstmt := REPLACE(_delchildstmt, '[done]',  _rt.recurtype_donecheck);
  _delchildstmt := REPLACE(_delchildstmt, '[schedcol]', _rt.recurtype_schedcol);

  _delparentstmt := REPLACE(_delparentstmt, '[fulltable]', _rt.recurtype_table);
  _delparentstmt := REPLACE(_delparentstmt, '[table]',
                            REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
  _delparentstmt := REPLACE(_delparentstmt, '[done]',  _rt.recurtype_donecheck);
  _delparentstmt := REPLACE(_delparentstmt, '[schedcol]', _rt.recurtype_schedcol);

  RAISE DEBUG 'substitutions changed _delchildstmt to %', _delchildstmt;

  IF (_rt.recurtype_delfunc IS NULL) THEN
    -- 8.4+: EXECUTE _delchildstmt  USING pDatetime, pType;
    RAISE DEBUG '% with % and %', _delchildstmt, pType, pDatetime;
    EXECUTE REPLACE(REPLACE(_delchildstmt, '$1', pParentid::TEXT),
                                           '$2', pDatetime::TEXT);
    GET DIAGNOSTICS _count = ROW_COUNT;

    IF (pInclParent) THEN
      -- 8.4+: EXECUTE _delparentstmt USING pDatetime, pType;
      RAISE DEBUG '% with % and %', _delparentstmt, pType, pDatetime;
      EXECUTE REPLACE(REPLACE(_delparentstmt, '$1', pParentid::TEXT),
                                              '$2', pDatetime::TEXT);
      GET DIAGNOSTICS _tmp   = ROW_COUNT;
      _count := _count + _tmp;
    END IF;

  ELSE
    -- 8.4+: FOR _tmp IN EXECUTE _delchildstmt USING pDatetime, pType LOOP
    FOR _tmp IN EXECUTE REPLACE(REPLACE(_delchildstmt, '$1', pParentid::TEXT),
                                                       '$2', pDatetime::TEXT)
    LOOP
      IF _tmp < 0 THEN
        RETURN _tmp;
      END IF;
      _count := _count + 1;
    END LOOP;

    IF (pInclParent) THEN
      -- 8.4+: EXECUTE _delparentstmt INTO _tmp USING pDatetime, pType;
      EXECUTE REPLACE(REPLACE(_delparentstmt, '$1', pParentid::TEXT),
                                              '$2', pDatetime::TEXT) INTO _tmp;
      IF (_tmp < 0) THEN
        RETURN _tmp;
      END IF;
      _count := _count + 1;
    END IF;
  END IF;

  RAISE DEBUG 'deleteOpenrecurringItems() returning %', _count;
  RETURN _count;
END;

Function: public.deleteopportunity(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOpheadid ALIAS FOR $1;
  _test INTEGER;
BEGIN

  SELECT todoitem_id INTO _test
    FROM todoitem
   WHERE(todoitem_ophead_id=pOpheadid)
   LIMIT 1;
  IF(FOUND) THEN
    RETURN -1;
  END IF;

  SELECT quhead_id INTO _test
    FROM quhead
   WHERE(quhead_ophead_id=pOpheadid)
   LIMIT 1;
  IF(FOUND) THEN
    RETURN -2;
  END IF;

  SELECT cohead_id INTO _test
    FROM cohead
   WHERE(cohead_ophead_id=pOpheadid)
   LIMIT 1;
  IF(FOUND) THEN
    RETURN -3;
  END IF;

  DELETE
    FROM charass
   WHERE((charass_target_type='OPP')
     AND (charass_target_id=pOpheadid));

  DELETE
    FROM comment
   WHERE((comment_source='OPP')
     AND (comment_source_id=pOpheadid));

  DELETE
    FROM ophead
   WHERE(ophead_id=pOpheadid);
  
  return 0;
END;

Function: public.deletepackage(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgheadid    ALIAS FOR $1;
  _i            INTEGER := 0;
  _pkgname      TEXT;
  _r            RECORD;
  _tabs         TEXT[] := ARRAY['cmd',  'cmdarg', 'image',  'metasql',
                                'priv', 'report', 'script', 'uiform'];
  _debug        BOOL := false;

BEGIN
  IF (EXISTS(SELECT *
             FROM pkgdep
             WHERE (pkgdep_parent_pkghead_id=ppkgheadid))) THEN
    RETURN -1;
  END IF;

  SELECT pkghead_name INTO _pkgname
  FROM pkghead
  WHERE (pkghead_id=ppkgheadid);
  IF (NOT FOUND) THEN
    RETURN -2;
  END IF;

  IF (LOWER(_pkgname) = 'public' OR LOWER(_pkgname) = 'api') THEN
    RETURN -3;
  END IF;

  FOR _i IN ARRAY_LOWER(_tabs,1)..ARRAY_UPPER(_tabs,1) LOOP
    EXECUTE 'ALTER TABLE ' || _pkgname || '.pkg' || _tabs[_i] ||
            ' DISABLE TRIGGER pkg' || _tabs[_i] || 'altertrigger;';
  END LOOP;

  DELETE FROM pkghead WHERE pkghead_id=ppkgheadid;

  RETURN ppkgheadid;
END;

Function: public.deletepo(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;
  _poitemid INTEGER;

BEGIN

  IF ( ( SELECT pohead_status
         FROM pohead
         WHERE (pohead_id=pPoheadid) ) = 'U' ) THEN

    -- Unlink from any Sales Orders
    UPDATE coitem SET coitem_order_type=NULL,
                      coitem_order_id=NULL
    FROM poitem 
    WHERE ( (coitem_order_type='P')
      AND   (coitem_order_id=poitem_id)
      AND   (poitem_pohead_id=pPoheadid) );

    DELETE FROM poitem
    WHERE (poitem_pohead_id=pPoheadid);

    DELETE FROM pohead
    WHERE (pohead_id=pPoheadid);

    RETURN TRUE;

  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.deletepoitem(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoitemid ALIAS FOR $1;
  _poheadid INTEGER := -1;
  _status CHARACTER;

BEGIN
  SELECT poitem_pohead_id, poitem_status INTO _poheadid, _status
  FROM poitem
  WHERE (poitem_id=pPoitemid);

  IF NOT(FOUND) THEN
    RETURN 0;
  END IF;

  IF ( _status = 'U' ) THEN
    DELETE FROM poitem
    WHERE (poitem_id=pPoitemid);
  ELSE   
    IF ( _status = 'O' ) THEN
      PERFORM recv_id
      FROM recv
      WHERE ( (recv_order_type='PO')
       AND (recv_orderitem_id=pPoitemid) );
      IF (FOUND) THEN
        RETURN -10;
      ELSE
        RETURN -20;
      END IF;
    ELSE
      RETURN -10;
    END IF;
  END IF;

  PERFORM poitem_id
  FROM poitem
  WHERE poitem_pohead_id = _poheadid;

  IF NOT(FOUND) THEN
    DELETE FROM pohead
    WHERE (pohead_id = _poheadid);
  END IF;
  
  RETURN 0;

END;

Function: public.deletepr(bpchar, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentType ALIAS FOR $1;
  pParentId ALIAS FOR $2;

BEGIN

  DELETE FROM pr
  WHERE ((pr_status='O')
   AND (pr_order_type=pParentType)
   AND (pr_order_id=pParentId));

  RETURN TRUE;

END;

Function: public.deletepr(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrid ALIAS FOR $1;

BEGIN

  DELETE FROM pr
  WHERE ( (pr_status='O')
   AND (pr_id=pPrid) );

  RETURN TRUE;

END;

Function: public.deleteproductcategory(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pProdcatid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if any items are assigned to the passed classcode
  SELECT item_id INTO _check
  FROM item
  WHERE (item_prodcat_id=pProdcatid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete any assocated records
  DELETE FROM salesaccnt
  WHERE (salesaccnt_prodcat_id=pProdcatid);

--  Delete the passed prodcat
  DELETE FROM prodcat
  WHERE (prodcat_id=pProdcatid);

  RETURN pProdcatid;

END;

Function: public.deleteprofitcenter(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pid ALIAS FOR $1;

BEGIN
  IF (EXISTS(SELECT accnt_id
             FROM accnt, prftcntr
             WHERE ((accnt_company=prftcntr_number)
               AND  (prftcntr_id=pid))
            )) THEN
    RETURN -1;
  END IF;

  DELETE FROM prftcntr
  WHERE (prftcntr_id=pid);

  RETURN pid;

END;

Function: public.deleteproject(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjid ALIAS FOR $1;
  _result INTEGER;
BEGIN

  SELECT quhead_id INTO _result
    FROM quhead
   WHERE (quhead_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  SELECT cohead_id INTO _result
    FROM cohead
   WHERE (cohead_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  SELECT wo_id INTO _result
    FROM wo
   WHERE (wo_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  SELECT pr_id INTO _result
    FROM pr
   WHERE (pr_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  SELECT poitem_id INTO _result
    FROM poitem
   WHERE (poitem_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

  SELECT invchead_id INTO _result
    FROM invchead
   WHERE (invchead_prj_id=pPrjid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -6;
  END IF;

  DELETE FROM comment
  WHERE ((comment_source='J')
  AND (comment_source_id=pPrjid));

  DELETE FROM comment
  WHERE ((comment_source='TA')
  AND (comment_source_id IN (
    SELECT prjtask_id
    FROM prjtask
    WHERE (prjtask_prj_id=pPrjId))));

  DELETE FROM prjtask
   WHERE (prjtask_prj_id=pPrjid);

  UPDATE prj
     SET prj_recurring_prj_id=null
   WHERE(prj_recurring_prj_id=pPrjid);

  DELETE FROM prj
   WHERE (prj_id=pPrjid);
  RETURN pPrjid;
END;

Function: public.deleteprojecttask(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjtaskid ALIAS FOR $1;
  _row RECORD;
  _result INTEGER;
BEGIN

  SELECT * INTO _row
    FROM prjtask
   WHERE (prjtask_id=pPrjtaskid)
   LIMIT 1;
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  IF (COALESCE(_row.prjtask_hours_actual, 0.0) > 0.0) THEN
    RETURN -2;
  END IF;

  IF (COALESCE(_row.prjtask_exp_actual, 0.0) > 0.0) THEN
    RETURN -3;
  END IF;

  DELETE FROM comment
  WHERE ((comment_source='TA')
  AND (comment_source_id=pPrjtaskid));

  DELETE FROM prjtask
   WHERE (prjtask_id=pPrjtaskid);

  RETURN 0;

END;

Function: public.deleteqryhead(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pqryheadid    ALIAS FOR $1;

BEGIN
  DELETE FROM qryitem WHERE (qryitem_qryhead_id=pqryheadid);
  DELETE FROM qryhead WHERE (qryhead_id=pqryheadid);

  RETURN pqryheadid;
END;

Function: public.deletequote(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
BEGIN
  RETURN deleteQuote(pQuheadid, NULL::TEXT);
END;

Function: public.deletequote(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid ALIAS FOR $1;
  pQuoteNumber	ALIAS FOR $2;
BEGIN
  RETURN deleteQuote(pQuheadid, pQuoteNumber::TEXT);
END;

Function: public.deletequote(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuheadid	ALIAS FOR $1;
  pQuoteNumber	ALIAS FOR $2;

  _quNumberScheme	TEXT;
  _quoteNumber		TEXT;
  _quitemid             INTEGER;
  _result               INTEGER;

BEGIN

  SELECT fetchMetricText('QUNumberGeneration') INTO _quNumberScheme;

  IF (pQuoteNumber IS NULL) THEN
    SELECT quhead_number INTO _quoteNumber
    FROM quhead
    WHERE (quhead_id=pQuheadid);
  ELSE
    _quoteNumber := pQuoteNumber;
  END IF;

  DELETE FROM quitem
  WHERE (quitem_quhead_id=pQuheadid);

  DELETE FROM quhead
  WHERE (quhead_id=pQuheadid);

  IF (_quoteNumber IS NOT NULL) THEN
    IF (_quNumberScheme IN ('A', 'O')) THEN
      -- do not release quote # if quote converted to sales order
      IF (NOT EXISTS (SELECT cohead_id
		      FROM cohead
		      WHERE (cohead_number=_quoteNumber))) THEN
	_result = releaseQuNumber(_quoteNumber);
      END IF;
    ELSEIF (_quNumberScheme = 'S') THEN
      _result = releaseSoNumber(_quoteNumber);
    END IF;
  END IF;

  -- Don't care about result of release number
  RETURN 0;

END;

Function: public.deleterecvfororder(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  porderid	ALIAS FOR $2;

BEGIN
  DELETE FROM recv
  USING orderitem
  WHERE ((recv_orderitem_id=orderitem_id)
    AND  (recv_order_type=orderitem_orderhead_type)
    AND  (NOT recv_posted)
    AND  (orderitem_orderhead_id=porderid)
    AND  (orderitem_orderhead_type=pordertype));

  RETURN 0;

END;

Function: public.deletesalescategory(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalescatid ALIAS FOR $1;

BEGIN

  PERFORM invcitem_salescat_id
  FROM invchead, invcitem
  WHERE ( (invcitem_invchead_id=invchead_id)
   AND (NOT invchead_posted)
   AND (invcitem_salescat_id=pSalescatid) );
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  PERFORM invcitem_salescat_id
  FROM invchead, invcitem
  WHERE ( (invcitem_invchead_id=invchead_id)
   AND (invchead_posted)
   AND (invcitem_salescat_id=pSalescatid) );
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  PERFORM aropen_salescat_id
     FROM aropen
    WHERE (aropen_salescat_id=pSalescatid);
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  DELETE FROM salescat
  WHERE (salescat_id=pSalescatid);

  RETURN 0;

END;

Function: public.deletesaletype(psaletypeid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _check INTEGER;

BEGIN

--  Check to see if any sales orders are assigned to the passed saletype
  SELECT cohead_id INTO _check
  FROM cohead
  WHERE (cohead_saletype_id=pSaletypeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Check to see if any quotes are assigned to the passed saletype
  SELECT quhead_id INTO _check
  FROM quhead
  WHERE (quhead_saletype_id=pSaletypeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to see if any invoice are assigned to the passed saletype
  SELECT invchead_id INTO _check
  FROM invchead
  WHERE (invchead_saletype_id=pSaletypeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to see if any credit memos are assigned to the passed saletype
  SELECT cmhead_id INTO _check
  FROM cmhead
  WHERE (cmhead_saletype_id=pSaletypeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

--  Delete the passed saletype
  DELETE FROM saletype
  WHERE (saletype_id=pSaletypeid);

  RETURN pSaletypeid;

END;

Function: public.deleteshippingcharge(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipchrgid ALIAS FOR $1;

BEGIN

  IF EXISTS(SELECT 1
              FROM custinfo
             WHERE (cust_shipchrg_id=pShipchrgid)) THEN
    RETURN -1;
  END IF;

  DELETE FROM shipchrg
  WHERE (shipchrg_id=pShipchrgid);

  RETURN pShipchrgid;

END;

Function: public.deleteshippingchargetype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipchrgid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if the passed shipchrg is used as a default for any customers
  SELECT cust_id INTO _check
  FROM custinfo
  WHERE (cust_shipchrg_id=pShipchrgid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Check to see if the passed shipchrg is used as a default for any shiptos
  SELECT shipto_id INTO _check
  FROM shiptoinfo
  WHERE (shipto_shipchrg_id=pShipchrgid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  Check to see if the passed shipchrg is used on any sales orders
  SELECT cohead_id INTO _check
  FROM cohead
  WHERE (cohead_shipchrg_id=pShipchrgid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

--  Check to see if the passed shipchrg is used on any shippers
  SELECT shiphead_id INTO _check
  FROM shiphead
  WHERE (shiphead_shipchrg_id=pShipchrgid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

--  Check to see if the passed shipchrg is used on any invoices
  SELECT invchead_id INTO _check
  FROM invchead
  WHERE (invchead_shipchrg_id=pShipchrgid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

--  Delete the passed shipchrg
  DELETE FROM shipchrg
  WHERE (shipchrg_id=pShipchrgid);

  RETURN pShipchrgid;

END;

Function: public.deleteshipto(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShiptoid ALIAS FOR $1;

BEGIN

  PERFORM asohist_id
  FROM asohist
  WHERE (asohist_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  PERFORM cohead_id
  FROM cohead
  WHERE (cohead_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  PERFORM cmhead_id
  FROM cmhead
  WHERE (cmhead_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  PERFORM cohist_id
  FROM cohist
  WHERE (cohist_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -4;
  END IF;

  PERFORM quhead_id
  FROM quhead
  WHERE (quhead_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -5;
  END IF;

  PERFORM invchead_id
  FROM invchead
  WHERE (invchead_shipto_id=pShiptoid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -6;
  END IF;

  DELETE FROM ipsass
  WHERE (ipsass_shipto_id=pShiptoid);

  DELETE FROM shiptoinfo
  WHERE (shipto_id=pShiptoid);

  RETURN 0;

END;

Function: public.deleteso(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid    ALIAS FOR $1;
BEGIN
  RETURN deleteSo(pSoheadid, NULL);
END;

Function: public.deleteso(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid	ALIAS FOR $1;
  pSonumber	ALIAS FOR $2;

  _r            RECORD;
  _coitemid     INTEGER;
  _result       INTEGER;
  _poStatus     INTEGER := 0;

BEGIN
-- Get cohead
  SELECT * INTO _r FROM cohead WHERE (cohead_id=pSoheadid);

   IF (NOT FOUND) THEN
     RETURN 0;
   END IF;

-- Cannot delete if credit card payments
  IF (EXISTS(SELECT ccpay_id
	     FROM ccpay, payco
	     WHERE ((ccpay_status IN ('C'))
	       AND  (ccpay_id=payco_ccpay_id)
	       AND  (payco_cohead_id=pSoheadid)))) THEN
    RETURN -1;
  END IF;

-- Cannot delete if credit card history
  IF (EXISTS(SELECT ccpay_id
	     FROM ccpay, payco
	     WHERE ((ccpay_status != 'C')
	       AND  (ccpay_id=payco_ccpay_id)
	       AND  (payco_cohead_id=pSoheadid)))) THEN
    RETURN -2;
  END IF;

-- Delete Sales Order Items
  FOR _coitemid IN
    SELECT coitem_id
    FROM coitem
    WHERE ( (coitem_cohead_id=pSoheadid)
      AND   (coitem_subnumber=0) ) LOOP

    SELECT deleteSoItem(_coitemid) INTO _result;
    IF (_result < 0) THEN
      IF (_result = -20) THEN
        _poStatus := _poStatus - 1;
      ELSE
        RETURN _result;
      END IF;
    END IF;

  END LOOP;

  DELETE FROM pack
  WHERE (pack_head_id=pSoheadid and pack_head_type = 'SO');

  DELETE FROM cohead
  WHERE (cohead_id=pSoheadid);

  IF (fetchMetricBool('AutoCreateProjectsForOrders')) THEN
    PERFORM deleteProject(_r.cohead_prj_id);
  END IF;

  DELETE FROM aropenalloc
  WHERE ((aropenalloc_doctype='S')
    AND  (aropenalloc_doc_id=pSoheadid));

  IF (COALESCE(pSonumber,'') != '') THEN
    _result = releaseSoNumber(pSonumber);
  ELSEIF (_r.cohead_number IS NOT NULL) THEN
    _result = releaseSoNumber(_r.cohead_number);
  END IF;

  IF (_poStatus < 0) THEN
    RETURN -20;
  ELSE
    RETURN 0;
  END IF;

END;

Function: public.deletesoitem(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemid	ALIAS FOR $1;

  _r            RECORD;
  _s            RECORD;
  _result       INTEGER;
  _deletePO     INTEGER := 0;
  _recvId       INTEGER := -1;
  _poStatus     TEXT;
  _jobItem      BOOLEAN;

BEGIN
-- Get coitem
   SELECT * INTO _r FROM coitem WHERE (coitem_id=pSoitemid);

   IF (NOT FOUND) THEN
     RETURN -999;
   END IF;

-- Cannot delete if shipped
  IF (_r.coitem_qtyshipped > 0) THEN
    RETURN -101;
  END IF;

-- Cannot delete if issued to shipping
  SELECT shipitem_id INTO _result
  FROM shipitem JOIN shiphead ON (shiphead_id=shipitem_shiphead_id AND shiphead_order_type='SO')
  WHERE (shipitem_orderitem_id=pSoitemid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -102;
  END IF;

-- Cannot delete if returned
  IF (fetchMetricBool('MultiWhs')) THEN
    SELECT raitem_id INTO _result
    FROM raitem
    WHERE ( (raitem_orig_coitem_id=pSoitemid)
       OR   (raitem_new_coitem_id=pSoitemid) )
    LIMIT 1;
    IF (FOUND) THEN
      RETURN -103;
    END IF;
  END IF;

-- Cannot delete if any inventory history
  SELECT invhist_id INTO _result
  FROM invhist
  WHERE ( (invhist_ordnumber=formatSoNumber(pSoitemid))
    AND   (invhist_ordtype='SO') )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -105;
  END IF;

-- If Kit, check deletion of component items
  FOR _s IN
    SELECT a.*
    FROM coitem a, (SELECT DISTINCT coitem_cohead_id,
                           coitem_linenumber
                    FROM coitem
                    WHERE coitem_id = pSoitemid) b
    WHERE ((a.coitem_cohead_id = b.coitem_cohead_id)
       AND (a.coitem_linenumber = b.coitem_linenumber)
       AND (a.coitem_subnumber > 0))
  LOOP
    IF ((COALESCE(_s.coitem_order_id, -1) > 0)
     AND (_s.coitem_order_type = 'P')) THEN
      SELECT poitem_status, COALESCE(recv_id, -1)
        INTO _poStatus, _recvId
      FROM poitem LEFT OUTER JOIN recv
             ON ((recv_orderitem_id=poitem_id)
               AND (recv_order_type='PO'))
      WHERE (poitem_id = _s.coitem_order_id);

      IF ((_recvId > 0) OR (_poStatus = 'C')) THEN
        RETURN -10;
      ELSIF ((_recvId = -1) AND (_poStatus = 'O')) THEN
        _deletePO := _deletePO - 1;
      END IF;
    END IF;
  END LOOP;


  SELECT (itemsite_costmethod='J') INTO _jobItem
  FROM coitem JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
  WHERE (coitem_id=pSoitemid);

  IF (_jobItem AND _r.coitem_order_type='W') THEN
-- Delete associated Job Work Order
    SELECT deleteWo(_r.coitem_order_id, TRUE, TRUE) INTO _result;
    IF (_result < 0) THEN
      RETURN -104;
    END IF;
  ELSIF (_r.coitem_order_type='W') THEN
-- Delete associated Job Work Order
    SELECT deleteWo(_r.coitem_order_id, TRUE) INTO _result;
    IF (_result < 0) THEN
      -- Cannot delete so break association
      PERFORM changeWoProject(_r.coitem_order_id, -1, TRUE);
    END IF;
  ELSIF (_r.coitem_order_type='R') THEN
-- Delete associated Purchase Request
    PERFORM deletePr(_r.coitem_order_id);
  ELSIF (_r.coitem_order_type='P') THEN
-- Delete associated Purchase Order Item
    SELECT deletepoitem(_r.coitem_order_id) INTO _result;
    IF ((_result < 0) AND (_result <> -20)) THEN
      RETURN _result;
    ELSIF (_result = -20) THEN
      _deletePO := _deletePO - 1;
    END IF;
  END IF;

-- Delete the coitem
  DELETE FROM coitem
  WHERE (coitem_id=pSoitemid);

  IF (_deletePO < 0) THEN
    RETURN -20;
  ELSE
    RETURN 0;
  END IF;

END;

Function: public.deletestandardjournal(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlid ALIAS FOR $1;

BEGIN

  DELETE FROM stdjrnlitem
  WHERE (stdjrnlitem_stdjrnl_id=pStdjrnlid);

  DELETE FROM stdjrnlgrpitem
  WHERE (stdjrnlgrpitem_stdjrnl_id=pStdjrnlid);

  DELETE FROM stdjrnl
  WHERE (stdjrnl_id=pStdjrnlid);

  RETURN 1;

END;

Function: public.deletestandardjournalgroup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlgrpid ALIAS FOR $1;

BEGIN

  DELETE FROM stdjrnlgrpitem
  WHERE (stdjrnlgrpitem_stdjrnlgrp_id=pStdjrnlgrpid);

  DELETE FROM stdjrnlgrp
  WHERE (stdjrnlgrp_id=pStdjrnlgrpid);

  RETURN 1;

END;

Function: public.deletesubaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pid ALIAS FOR $1;

BEGIN
  IF (EXISTS(SELECT accnt_id
             FROM accnt, subaccnt
             WHERE ((accnt_company=subaccnt_number)
               AND  (subaccnt_id=pid))
            )) THEN
    RETURN -1;
  END IF;

  DELETE FROM subaccnt
  WHERE (subaccnt_id=pid);

  RETURN pid;

END;

Function: public.deletesubaccounttype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSubAccntTypeid ALIAS FOR $1;
  _check INTEGER;

BEGIN

--  Check to see if the passed subaccnttype is used in any accounts
  SELECT accnt_id INTO _check
  FROM accnt, subaccnttype
  WHERE ( (accnt_subaccnttype_code=subaccnttype_code)
   AND (subaccnttype_id=pSubAccntTypeid) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the Sub Account Type
  DELETE FROM subaccnttype
  WHERE (subaccnttype_id=pSubAccntTypeid);

  RETURN 0;

END;

Function: public.deletetax(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptaxid	ALIAS FOR $1;
BEGIN
  -- these checks allow nice error reporting instead of throwing an SQL error
  IF EXISTS(SELECT taxass_id FROM taxass WHERE (taxass_tax_id=ptaxid)) THEN
    RETURN -10;
  END IF;
  IF EXISTS(SELECT taxhist_id FROM taxhist WHERE (taxhist_tax_id=ptaxid)) THEN
    RETURN -20;
  END IF;

  DELETE FROM taxrate WHERE (taxrate_tax_id = ptaxid);
  DELETE FROM tax WHERE (tax_id = ptaxid);

  RETURN ptaxid;

END;

Function: public.deletetaxclass(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pTaxclassid ALIAS FOR $1;
_result INTEGER;

BEGIN

-- Check to find if the tax class is used in any tax code
SELECT tax_id INTO _result
FROM tax
WHERE (tax_taxclass_id = pTaxclassid);
IF (FOUND) THEN
   RETURN -1;
END IF;

-- Delete the tax class if the above condition doesn't match
DELETE FROM taxclass WHERE taxclass_id = pTaxclassid ;

RETURN pTaxclassid;

END;

Function: public.deletetaxtype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxtypeid ALIAS FOR $1;
  _result INTEGER;
BEGIN

  SELECT taxtype_id
    INTO _result
    FROM taxtype
   WHERE ((taxtype_sys)
     AND  (taxtype_id=pTaxtypeid));
  IF (FOUND) THEN
    RETURN -1;
  END IF;

  SELECT taxass_id
    INTO _result
    FROM taxass
   WHERE (taxass_taxtype_id=pTaxtypeid);
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  SELECT taxhist_id
    INTO _result
    FROM taxhist
   WHERE (taxhist_taxtype_id=pTaxtypeid);
  IF (FOUND) THEN
    RETURN -3;
  END IF;

  DELETE
    FROM taxtype
   WHERE (taxtype_id=pTaxtypeid);

  RETURN pTaxtypeid;

END;

Function: public.deletetaxzone(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pTaxzoneid ALIAS FOR $1;
_result INTEGER;

BEGIN

-- Check to find if the tax zone is used in any tax assignment
SELECT taxass_id INTO _result
FROM taxass
WHERE (taxass_taxzone_id=pTaxzoneid);
IF (FOUND) THEN
   RETURN -1;
END IF;

-- Check to find if the tax zone has been referenced in any tax registration
SELECT taxreg_id INTO _result 
FROM taxreg
WHERE (taxreg_taxzone_id=pTaxzoneid);
IF (FOUND) THEN
   RETURN -2;
END IF;

-- Delete the tax zone if none of the above conditions match
DELETE FROM taxzone WHERE taxzone_id = pTaxzoneid ;

RETURN pTaxzoneid;

END;

Function: public.deletetodoitem(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoItemId ALIAS FOR $1;
BEGIN
  DELETE FROM alarm WHERE ( (alarm_source='TODO') AND (alarm_source_id=ptodoItemId) );
  DELETE FROM todoitem WHERE todoitem_id = ptodoItemId;
  RETURN 0;
END;

Function: public.deleteunusedclasscodes()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  DELETE FROM classcode
  WHERE (classcode_id NOT IN (SELECT DISTINCT item_classcode_id FROM item));

  RETURN 0;

END;

Function: public.deleteunusedfreightclasses()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  DELETE FROM freightclass
  WHERE (freightclass_id NOT IN (SELECT DISTINCT COALESCE(item_freightclass_id, 0) FROM item));

  RETURN 0;

END;

Function: public.deleteunusedproductcategories()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

--  Delete any associated records
  DELETE FROM salesaccnt
  WHERE ( (salesaccnt_prodcat_id <> -1)
   AND (salesaccnt_prodcat_id NOT IN (SELECT DISTINCT item_prodcat_id FROM item)) );

  DELETE FROM prodcat
  WHERE (prodcat_id NOT IN (SELECT DISTINCT item_prodcat_id FROM item));

  RETURN 0;

END;

Function: public.deleteuom(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUomid ALIAS FOR $1;

BEGIN

  DELETE FROM uomconv WHERE uomconv_from_uom_id=pUomid;
  DELETE FROM uomconv WHERE uomconv_to_uom_id=pUomid;
  DELETE FROM uom WHERE uom_id=pUomid;

  RETURN 0;
END;

Function: public.deleteuomconv(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUomconvid ALIAS FOR $1;

BEGIN
  DELETE FROM uomconv WHERE uomconv_id=pUomconvid;

  RETURN 0;
END;

Function: public.deleteurl(integer)

Returns: boolean

Language: PLPGSQL

declare
  pId ALIAS FOR $1;
begin
  delete from urlinfo
  where ( url_id in (
    select url_id
    from urlinfo
      join docass on (docass_target_id=url_id)
                 and (docass_target_type='URL')
      where ( docass_id = pId ) ) );

  delete from docass where docass_id = pId;

  return true;
end;

Function: public.deleteuserpreference(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrefname ALIAS FOR $1;
  _return BOOLEAN;

BEGIN

  SELECT deleteUserPreference(getEffectiveXtUser(), pPrefname) INTO _return;

  RETURN _return;

END;

Function: public.deleteuserpreference(text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrefname ALIAS FOR $2;

BEGIN

  DELETE FROM usrpref
  WHERE ( (usrpref_username=pUsername)
   AND (usrpref_name=pPrefname) );

  RETURN TRUE;

END;

Function: public.deletevendoraddress(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendaddrid ALIAS FOR $1;
  _test INTEGER;

BEGIN

--  Check to see if the passed vendor address is used in pohead
  SELECT pohead_id INTO _test
  FROM pohead
  WHERE (pohead_vendaddr_id=pVendaddrid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the passed vendor address
  DELETE FROM vendaddrinfo
  WHERE (vendaddr_id=pVendaddrid);

  RETURN 0;

END;

Function: public.deletevendortype(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendtypeid ALIAS FOR $1;
  _test INTEGER;

BEGIN

--  Check to see if the passed vendor type is used in vendinfo
  SELECT vend_id INTO _test
  FROM vendinfo
  WHERE (vend_vendtype_id=pVendtypeid)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -1;
  END IF;

--  Delete the passed vendor type
  DELETE FROM vendtype
  WHERE (vendtype_id=pVendtypeid);

  RETURN 0;

END;

Function: public.deletewo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  deleteChildren ALIAS FOR $2;

BEGIN
  RETURN deleteWo(pWoid, deleteChildren, FALSE);
END;

Function: public.deletewo(integer, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  deleteChildren ALIAS FOR $2;
  deleteForce ALIAS FOR $3;
  woStatus CHAR(1);
  itemType CHAR(1);
  ordtype CHAR(1);
  ordid INTEGER;
  returnCode INTEGER;
  _wotcCnt	INTEGER;
  _routings BOOLEAN;

BEGIN
  SELECT wo_status, wo_ordtype, wo_ordid, item_type
  INTO   woStatus, ordtype, ordid, itemType
  FROM wo JOIN itemsite ON (itemsite_id=wo_itemsite_id)
          JOIN item ON (item_id=itemsite_item_id)
  WHERE (wo_id=pWoid);

  IF (NOT woStatus IN ('O', 'E', 'C')) THEN
    RETURN -3;
  END IF;

  IF (NOT deleteForce) THEN
    IF (itemType = 'J') THEN
      RETURN -2;
    END IF;
  END IF;

  SELECT fetchMetricBool('Routings') INTO _routings;

  IF _routings THEN
    SELECT count(*) INTO _wotcCnt
    FROM xtmfg.wotc
    WHERE (wotc_wo_id=pWoid);
    IF (_wotcCnt > 0) THEN
      RETURN -1;
    END IF;
  END IF;

  IF (woStatus = 'R') THEN
    INSERT INTO evntlog (evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
                         evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, evntlog_number)
    SELECT CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
           'W', wo_id, itemsite_warehous_id, formatWoNumber(wo_id)
    FROM evntnot, evnttype, itemsite, item, wo
    WHERE ( (evntnot_evnttype_id=evnttype_id)
     AND (evntnot_warehous_id=itemsite_warehous_id)
     AND (wo_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (evnttype_name='RWoRequestCancel')
     AND (wo_id=pWoid) );

     RETURN 0;
  ELSE
    IF (woStatus = 'E') THEN
      returnCode := (SELECT implodeWo(pWoid, FALSE));
    END IF;
  END IF;

  IF (woStatus IN ('O', 'E', 'C')) THEN
    DELETE FROM womatl
    WHERE (womatl_wo_id=pWoid);

    IF _routings THEN
      DELETE FROM xtmfg.wooper
      WHERE (wooper_wo_id=pWoid);
    END IF;

    IF (ordtype = 'S') THEN
      UPDATE coitem SET coitem_order_type=NULL, coitem_order_id=NULL
      WHERE coitem_id=ordid;
    END IF;

    DELETE FROM wo
    WHERE (wo_id=pWoid);
  END IF;

  IF (deleteChildren) THEN
    returnCode := (SELECT MAX(deleteWo(wo_id, TRUE))
                   FROM wo
                   WHERE ((wo_ordtype='W')
                    AND (wo_ordid=pWoid)));
  END IF;

  RETURN 0;
END;

Function: public.deletewomaterial(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;

BEGIN

  UPDATE wo
  SET wo_adhoc=TRUE
  FROM womatl
  WHERE ((womatl_wo_id=wo_id)
   AND (womatl_id=pWomatlid));

--  Delete any created P/R for this Womatl
  PERFORM deletePr('W', pWomatlid);

  DELETE FROM womatl
  WHERE (womatl_id=pWomatlid);

  RETURN 0;
END;

Function: public.detachccpayfromso(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcoheadid		ALIAS FOR $1;
  pwarehousid		ALIAS FOR $2;
  pcustid		ALIAS FOR $3;

BEGIN
  RAISE NOTICE 'detachCCPayFromSO(INTEGER, INTEGER, INTEGER): deprecated';
  RETURN 0;
END;

Function: public.detachcontact(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcntctId    ALIAS FOR $1;
  pcrmacctId  ALIAS FOR $2;
BEGIN
  UPDATE cntct SET cntct_crmacct_id = NULL
  WHERE cntct_id = pcntctId
    AND cntct_crmacct_id = pcrmacctId;

  UPDATE crmacct SET crmacct_cntct_id_1 = NULL
  WHERE crmacct_id = pcrmacctId
    AND crmacct_cntct_id_1 = pcntctId;

  UPDATE crmacct SET crmacct_cntct_id_2 = NULL
  WHERE crmacct_id = pcrmacctId
    AND crmacct_cntct_id_2 = pcntctId;

  RETURN 0;
END;

Function: public.detag(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource ALIAS FOR $1;
  _result TEXT := '';

BEGIN
  SELECT regexp_replace(pSource, E'<[^>]*>', '', 'g') INTO _result;
  RETURN _result;
END;

Function: public.detailednnqoh(integer, boolean)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pABS ALIAS FOR $2;
  _qoh NUMERIC;

BEGIN

  IF (pABS) THEN
    SELECT SUM(noNeg(itemloc_qty)) INTO _qoh
    FROM itemloc, location
    WHERE ( (itemloc_location_id=location_id)
     AND (NOT location_netable)
     AND (itemloc_itemsite_id=pItemsiteid) );
  ELSE
    SELECT SUM(itemloc_qty) INTO _qoh
    FROM itemloc, location
    WHERE ( (itemloc_location_id=location_id)
     AND (NOT location_netable)
     AND (itemloc_itemsite_id=pItemsiteid) );
  END IF;

  IF (_qoh IS NULL) THEN
    _qoh := 0;
  END IF;

  RETURN _qoh;

END;

Function: public.detailedqoh(integer, boolean)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pABS ALIAS FOR $2;
  _qoh NUMERIC;

BEGIN

  IF (pABS) THEN
    SELECT SUM(noNeg(itemloc_qty)) INTO _qoh
    FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
    WHERE ( ( (location_id IS NULL) OR (location_netable) )
     AND (itemloc_itemsite_id=pItemsiteid) );
  ELSE
    SELECT SUM(itemloc_qty) INTO _qoh
    FROM itemloc LEFT OUTER JOIN location ON (itemloc_location_id=location_id)
    WHERE ( ( (location_id IS NULL) OR (location_netable) )
     AND (itemloc_itemsite_id=pItemsiteid) );
  END IF;

  IF (_qoh IS NULL) THEN
    _qoh := 0;
  END IF;

  RETURN _qoh;

END;

Function: public.determinediscountdate(integer, date)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTermsid ALIAS FOR $1;
  pSourceDate ALIAS FOR $2;
  _discDate DATE;
  _p RECORD;

BEGIN

  SELECT terms_type, terms_discdays, terms_cutoffday INTO _p
  FROM terms
  WHERE (terms_id=pTermsid);
  IF (NOT FOUND) THEN
    _discDate := pSourceDate;

--  Handle type D terms
  ELSIF (_p.terms_type = 'D') THEN
    _discDate := (pSourceDate + _p.terms_discdays);

--  Handle type P terms
  ELSIF (_p.terms_type = 'P') THEN
    IF (date_part('day', pSourceDate) <= _p.terms_cutoffday) THEN
      _discDate := (DATE(date_trunc('month', pSourceDate)) + (_p.terms_discdays - 1));
    ELSE
      _discDate := (DATE(date_trunc('month', pSourceDate)) + (_p.terms_discdays - 1) + INTERVAL '1 month');
    END IF;

--  Handle unknown terms
  ELSE
    _discDate := pSourceDate;
  END IF;

  RETURN _discDate;

END;

Function: public.determineduedate(integer, date)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTermsid ALIAS FOR $1;
  pSourceDate ALIAS FOR $2;
  _dueDate DATE;
  _p RECORD;

BEGIN

  SELECT terms_type, terms_duedays, terms_cutoffday INTO _p
  FROM terms
  WHERE (terms_id=pTermsid);
  IF (NOT FOUND) THEN
    _dueDate := pSourceDate;

--  Handle type D terms
  ELSIF (_p.terms_type = 'D') THEN
    _dueDate := (pSourceDate + _p.terms_duedays);

--  Handle type P terms
  ELSIF (_p.terms_type = 'P') THEN
    IF (date_part('day', pSourceDate) <= _p.terms_cutoffday) THEN
      _dueDate := (DATE(date_trunc('month', pSourceDate)) + (_p.terms_duedays - 1));
    ELSE
      _dueDate := (DATE(date_trunc('month', pSourceDate)) + (_p.terms_duedays - 1) + INTERVAL '1 month');
    END IF;

--  Handle unknown terms
  ELSE
    _dueDate := pSourceDate;
  END IF;

  RETURN _dueDate;

END;

Function: public.digest(bytea, text)

Returns: bytea

Language: C

pg_digest

Function: public.digest(text, text)

Returns: bytea

Language: C

pg_digest

Function: public.disablepackage(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgheadid    ALIAS FOR $1;
  _pkgname      TEXT;

BEGIN
  SELECT pkghead_name INTO _pkgname
  FROM pkghead
  WHERE (pkghead_id=ppkgheadid);
  IF (NOT FOUND) THEN
    RETURN -2;
  END IF;

  RETURN disablePackage(_pkgname);
END;

Function: public.disablepackage(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgname ALIAS FOR $1;
  _i       INTEGER := 0;
  _tabs    TEXT[] := ARRAY['cmd',  'cmdarg', 'image',  'metasql',
                           'priv', 'report', 'script', 'uiform'];

BEGIN
  IF (version() < 'PostgreSQL 8.2') THEN
    RETURN -1;
  END IF;

  FOR _i IN ARRAY_LOWER(_tabs,1)..ARRAY_UPPER(_tabs,1) LOOP
    EXECUTE 'ALTER TABLE ' || ppkgname || '.pkg' || _tabs[_i] ||
            ' NO INHERIT public.' || _tabs[_i] || ';';
  END LOOP;
  
  RETURN 0;
END;

Function: public.distributeitemlocseries(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocSeries   ALIAS FOR $1;
  _distCounter     INTEGER;
  _itemlocdist     RECORD;
  _itemlocid       INTEGER;
  _invhistid       INTEGER;
  _check           BOOLEAN;
  _debug           BOOLEAN := true;
BEGIN

  IF (_debug) THEN
    RAISE NOTICE 'distributeItemlocSeries, series=%', pItemlocSeries;
  END IF;

  _distCounter := 0;

--  March through all of the itemlocdists for pItemlocSeries
  FOR _itemlocdist IN SELECT itemlocdist_id AS itemlocdistid,
                             itemlocdist_source_type AS type,
                             itemlocdist_source_id AS sourceid,
                             itemlocdist_qty AS qty,
                             itemlocdist_itemsite_id AS itemsiteid,
                             itemsite_freeze,
                             itemlocdist_invhist_id AS invhistid,
                             itemlocdist_ls_id AS lotserialid,
                             itemlocdist_expiration AS expiration,
                             itemlocdist_flush,
                             itemlocdist_warranty AS warranty,
                             itemlocdist_series AS series
                      FROM itemlocdist, itemsite
                      WHERE ( (itemlocdist_itemsite_id=itemsite_id)
                       AND (itemlocdist_series=pItemlocSeries) )
                      ORDER BY itemlocdist_flush DESC LOOP

    _distCounter := _distCounter + 1;
    IF (_debug) THEN
      RAISE NOTICE 'itemlocdist loop %', _distCounter;
      RAISE NOTICE 'itemlocdistid=%', _itemlocdist.itemlocdistid;
      RAISE NOTICE 'type=%', _itemlocdist.type;
      RAISE NOTICE 'sourceid=%', _itemlocdist.sourceid;
      RAISE NOTICE 'qty=%', _itemlocdist.qty;
      RAISE NOTICE 'itemsiteid=%', _itemlocdist.itemsiteid;
      RAISE NOTICE 'freeze=%', _itemlocdist.itemsite_freeze;
      RAISE NOTICE 'invhistid=%', _itemlocdist.invhistid;
      RAISE NOTICE 'lotserialid=%', _itemlocdist.lotserialid;
      RAISE NOTICE 'expiration=%', _itemlocdist.expiration;
      RAISE NOTICE 'flush=%', _itemlocdist.itemlocdist_flush;
      RAISE NOTICE 'warranty=%', _itemlocdist.warranty;
    END IF;

--  Commit invhist to itemsite
    IF (NOT _itemlocdist.itemsite_freeze) THEN
	PERFORM postInvHist(_itemlocdist.invhistid);
    END IF;

--  Mark the invhist tuple for the itemlocdist in question as having detail
    UPDATE invhist
    SET invhist_hasdetail=TRUE
    WHERE ( (NOT invhist_hasdetail)
     AND (invhist_id=_itemlocdist.invhistid) );

--  If this itemlocdist is a flush, write a invdetail tuple that records the empty
    IF (_itemlocdist.itemlocdist_flush) THEN
      INSERT INTO invdetail
      ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
        invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration,
        invdetail_warrpurc )
      SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
             (itemloc_qty * -1), itemloc_qty, 0, itemloc_expiration, 
             _itemlocdist.warranty
      FROM itemloc
      WHERE ( (itemloc_qty <> 0)
       AND (itemloc_id=_itemlocdist.sourceid) );

--  Delete the flushed itemloc if its parent itemsite is not frozen
      IF (NOT _itemlocdist.itemsite_freeze) THEN
        DELETE FROM itemloc
        WHERE (itemloc_id=_itemlocdist.sourceid);
      END IF;

    ELSE
--  If this is a location type distribution, check to see if the target itemloc
--  already exists
      IF (_itemlocdist.type = 'L') THEN
        SELECT itemloc_id INTO _itemlocid
        FROM itemloc
        WHERE ( (itemloc_itemsite_id=_itemlocdist.itemsiteid)
         AND (itemloc_location_id=_itemlocdist.sourceid)
         AND (COALESCE(itemloc_ls_id,-1)=COALESCE(_itemlocdist.lotserialid,-1))
         AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_itemlocdist.expiration,endOfTime()))
         AND (COALESCE(itemloc_warrpurc,endoftime())=COALESCE(_itemlocdist.warranty,endoftime())) );

--  Nope, create it
        IF (NOT FOUND) THEN
          SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;

          INSERT INTO itemloc
          ( itemloc_id, itemloc_itemsite_id,
            itemloc_location_id, itemloc_qty,
            itemloc_ls_id, itemloc_expiration,
            itemloc_warrpurc )
          VALUES
          ( _itemlocid, _itemlocdist.itemsiteid,
            _itemlocdist.sourceid, 0,
            _itemlocdist.lotserialid, _itemlocdist.expiration,
            _itemlocdist.warranty );
        END IF;

      ELSE
        _itemlocid = _itemlocdist.sourceid;

        IF (_itemlocid IS NOT NULL AND (SELECT count(itemloc_id) = 0 FROM itemloc WHERE itemloc_id=_itemlocid)) THEN
          RAISE EXCEPTION 'No record to distribute against. Someone else may have already distributed this record.';
        END IF;
      END IF;

--  Record the invdetail
      INSERT INTO invdetail
      (invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
       invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration,
       invdetail_warrpurc)
      SELECT _itemlocdist.invhistid, itemloc_location_id, _itemlocdist.lotserialid,
             _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
             itemloc_expiration,_itemlocdist.warranty
      FROM itemloc
      WHERE (itemloc_id=_itemlocid);

--  Update the itemloc_qty if its parent itemsite is not frozen
      IF (NOT _itemlocdist.itemsite_freeze) THEN
        UPDATE itemloc
        SET itemloc_qty = (itemloc_qty + _itemlocdist.qty)
        WHERE (itemloc_id=_itemlocid);
      END IF;

--  Adjust QOH if this itemlocdist is to/from a non-netable location
      IF ( SELECT (NOT location_netable)
           FROM itemloc, location
           WHERE ( (itemloc_location_id=location_id)
            AND (itemloc_id=_itemlocid) ) ) THEN

--  Record the netable->non-netable (or visaveras) invhist
        SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
        INSERT INTO invhist
        ( invhist_id, invhist_itemsite_id, 
          invhist_transtype, invhist_invqty,
          invhist_qoh_before, invhist_qoh_after,
          invhist_docnumber, invhist_comments,
          invhist_invuom, invhist_unitcost,
          invhist_costmethod, invhist_value_before, invhist_value_after,
          invhist_series ) 
        SELECT _invhistid, itemsite_id, 
               'NN', (_itemlocdist.qty * -1),
               itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
               invhist_docnumber, invhist_comments,
               uom_name, stdCost(item_id),
               itemsite_costmethod, itemsite_value,
               (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
                                                               ELSE stdCost(itemsite_item_id)
                                                          END)),
               _itemlocdist.series
        FROM item, itemsite, invhist, uom
        WHERE ((itemsite_item_id=item_id)
         AND (item_inv_uom_id=uom_id)
         AND (itemsite_controlmethod <> 'N')
         AND (itemsite_id=_itemlocdist.itemsiteid)
         AND (invhist_id=_itemlocdist.invhistid));

--  Adjust the parent itemsite
        IF (NOT _itemlocdist.itemsite_freeze) THEN
          UPDATE itemsite
          SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
              itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
          FROM itemloc
          WHERE ((itemloc_itemsite_id=itemsite_id)
           AND (itemloc_id=_itemlocid));
        END IF;
      END IF;

    END IF;

--  If, after the distribution, the target itemloc_qty = 0, delete the itemloc
--  if its parent itemsite is not frozen
    IF (NOT _itemlocdist.itemsite_freeze) THEN
      DELETE FROM itemloc
      WHERE ( (itemloc_qty=0)
       AND (itemloc_id=_itemlocid) );
    END IF;

  END LOOP;

  DELETE FROM itemlocdist
  WHERE (itemlocdist_series=pItemlocSeries);

  RETURN _distCounter;

END;

Function: public.distributetodefault(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocdistid ALIAS FOR $1;

BEGIN

  RETURN distributeToDefault(pItemlocdistid, 'O');

END;

Function: public.distributetodefault(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocdistid ALIAS FOR $1;
  pTranstype ALIAS FOR $2;
  _locationid INTEGER;
  _itemlocdistid INTEGER;
  _qty NUMERIC;

BEGIN

--  Make sure that the itemsite in question has a default location
  SELECT CASE WHEN (pTranstype='R') THEN itemsite_recvlocation_id
              WHEN (pTranstype='I') THEN itemsite_issuelocation_id
              ELSE itemsite_location_id
         END INTO _locationid
  FROM itemlocdist, itemsite
  WHERE ( (itemlocdist_itemsite_id=itemsite_id)
   AND (itemlocdist_id=pItemlocdistid) );
  IF ( (NOT FOUND) OR (_locationid = -1) ) THEN
    RETURN -1;
  END IF;

--  Determine the remaining qty required to distribute
  SELECT (p.itemlocdist_qty - COALESCE(SUM(c.itemlocdist_qty), 0)) INTO _qty
  FROM itemlocdist AS p LEFT OUTER JOIN itemlocdist AS c ON (c.itemlocdist_itemlocdist_id=p.itemlocdist_id)
  WHERE (p.itemlocdist_id=pItemlocdistid)
  GROUP BY p.itemlocdist_qty;

  IF (_qty = 0) THEN
    RETURN -2;
  END IF;

--  Check to see if an itemlocdist with the correct location/lotserial/expiration already exists
  SELECT target.itemlocdist_id INTO _itemlocdistid
  FROM itemlocdist AS source, itemlocdist AS target, itemloc, itemsite
  WHERE ( (target.itemlocdist_source_type='L')
   AND (target.itemlocdist_source_id=_locationid)
   AND (target.itemlocdist_itemsite_id=source.itemlocdist_itemsite_id)
   AND (COALESCE(target.itemlocdist_ls_id)=COALESCE(source.itemlocdist_ls_id))
   AND (target.itemlocdist_expiration=source.itemlocdist_expiration)
   AND (target.itemlocdist_itemlocdist_id=source.itemlocdist_itemlocdist_id)
   AND (target.itemlocdist_itemsite_id=itemsite_id)
   AND (source.itemlocdist_id=pItemlocdistid) );

  IF (FOUND) THEN
    UPDATE itemlocdist
    SET itemlocdist_qty = (itemlocdist_qty + _qty)
    WHERE (itemlocdist_id=_itemlocdistid);

    RETURN _itemlocdistid;
  END IF;

--  Create a new itemlocdist
  SELECT NEXTVAL('itemlocdist_itemlocdist_id_seq') INTO _itemlocdistid;

  INSERT INTO itemlocdist
  ( itemlocdist_id, itemlocdist_itemlocdist_id, itemlocdist_source_type,
    itemlocdist_ls_id, itemlocdist_expiration,
    itemlocdist_source_id, itemlocdist_itemsite_id, itemlocdist_qty )
  SELECT _itemlocdistid, pItemlocdistid, 'L',
         itemlocdist_ls_id, itemlocdist_expiration,
         _locationid, itemlocdist_itemsite_id, _qty
  FROM itemlocdist
  WHERE (itemlocdist_id=pItemlocdistid);

  RETURN _itemlocdistid;

END;

Function: public.distributetodefaultitemloc(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocdistid ALIAS FOR $1;

BEGIN

  RETURN distributeToDefaultItemLoc(pItemlocdistid, 'O');

END;

Function: public.distributetodefaultitemloc(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocdistid ALIAS FOR $1;
  pTranstype ALIAS FOR $2;
  _itemlocid INTEGER;
  _itemlocdistid INTEGER;
  _qty NUMERIC;

BEGIN

--  Make sure that the itemsite in question has a default location
  SELECT itemloc_id INTO _itemlocid
    FROM itemlocdist, itemsite, itemloc
   WHERE ((itemlocdist_itemsite_id=itemsite_id)
     AND ( (itemsite_location_id=itemloc_location_id AND pTranstype='O') OR
           (itemsite_recvlocation_id=itemloc_location_id AND pTranstype='R') OR
           (itemsite_issuelocation_id=itemloc_location_id AND pTranstype='I') )
     AND (itemloc_itemsite_id=itemsite_id)
     AND (itemlocdist_id=pItemlocdistid));
  IF ( (NOT FOUND) OR (_itemlocid = -1) ) THEN
    RETURN -1;
  END IF;

--  Determine the remaining qty required to distribute
  SELECT (p.itemlocdist_qty - COALESCE(SUM(c.itemlocdist_qty), 0)) INTO _qty
    FROM itemlocdist AS p LEFT OUTER JOIN itemlocdist AS c
      ON (c.itemlocdist_itemlocdist_id=p.itemlocdist_id)
   WHERE (p.itemlocdist_id=pItemlocdistid)
   GROUP BY p.itemlocdist_qty;

  IF (_qty = 0) THEN
    RETURN -2;
  END IF;

--  Check to see if an itemlocdist with the correct location/lotserial/expiration already exists
  SELECT target.itemlocdist_id INTO _itemlocdistid
  FROM itemlocdist AS source, itemlocdist AS target
  WHERE ( (target.itemlocdist_source_type='I')
   AND (target.itemlocdist_source_id=_itemlocid)
   AND (COALESCE(target.itemlocdist_ls_id,-1)=COALESCE(source.itemlocdist_ls_id,-1))
   AND (target.itemlocdist_expiration=source.itemlocdist_expiration)
   AND (target.itemlocdist_itemlocdist_id=source.itemlocdist_id)
   AND (source.itemlocdist_id=pItemlocdistid) );

  IF (FOUND) THEN
    UPDATE itemlocdist
    SET itemlocdist_qty = (itemlocdist_qty + _qty)
    WHERE (itemlocdist_id=_itemlocdistid);

    RETURN _itemlocdistid;
  END IF;

--  Create a new itemlocdist
  SELECT NEXTVAL('itemlocdist_itemlocdist_id_seq') INTO _itemlocdistid;

  INSERT INTO itemlocdist
  ( itemlocdist_id, itemlocdist_itemlocdist_id,
    itemlocdist_source_type, itemlocdist_source_id,
    itemlocdist_qty, itemlocdist_expiration )
  VALUES
  ( _itemlocdistid, pItemlocdistid,
    'I', _itemlocid,
    _qty, endOfTime() );

  RETURN _itemlocdistid;

END;

Function: public.distributetolocations(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocdistid ALIAS FOR $1;
  _distCounter INTEGER;
  _itemlocdist RECORD;
  _itemlocid INTEGER;
  _runningQty NUMERIC;
  _tmp RECORD;

BEGIN

  _distCounter := 0;
  _runningQty  := 0;

-- A scenario can occur where two people try to post distributions
-- to the same itemsite against two or more lot/serial/mlc locations
-- leading to a deadlock. This line tries to prevent that by locking
-- ahead of time all the itemsites that the transaction will need
-- before any of the other tables are locked individually.
  SELECT itemsite_id
    INTO _tmp
    FROM itemsite
   WHERE(itemsite_id in (SELECT DISTINCT itemlocdist_itemsite_id
                           FROM itemlocdist
                          WHERE(itemlocdist_id=pItemlocdistid)))
     FOR UPDATE;

--  March through all of the itemlocdist owned by the passed parent itemlocdist
  FOR _itemlocdist IN SELECT c.itemlocdist_id AS itemlocdistid,
                             c.itemlocdist_source_type AS type,
                             c.itemlocdist_source_id AS sourceid,
                             c.itemlocdist_qty AS qty,
                             p.itemlocdist_itemsite_id AS itemsiteid,
                             itemsite_freeze,
                             p.itemlocdist_invhist_id AS invhistid,
                             p.itemlocdist_ls_id AS lotserialid,
                             p.itemlocdist_expiration AS expiration,
                             p.itemlocdist_warranty AS warranty,
                             p.itemlocdist_order_type AS ordertype,
                             p.itemlocdist_order_id AS orderid,
                             p.itemlocdist_series AS series
                      FROM itemlocdist AS c, itemlocdist AS p, itemsite
                      WHERE ( (c.itemlocdist_itemlocdist_id=p.itemlocdist_id)
                       AND (p.itemlocdist_source_type='O')
                       AND (p.itemlocdist_itemsite_id=itemsite_id)
                       AND (p.itemlocdist_id=pItemlocdistid) ) LOOP

    _distCounter := _distCounter + 1;

--  If the target for this itemlocdist is a location, check to see if the
--  required itemloc already exists
    IF (_itemlocdist.type = 'L') THEN
      SELECT itemloc_id INTO _itemlocid
      FROM itemloc
      WHERE ( (itemloc_itemsite_id=_itemlocdist.itemsiteid)
       AND (itemloc_location_id=_itemlocdist.sourceid)
       AND (COALESCE(itemloc_ls_id, -1)=COALESCE(_itemlocdist.lotserialid, -1))
       AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_itemlocdist.expiration,endOfTime()))
       AND (COALESCE(itemloc_warrpurc,endoftime())=COALESCE(_itemlocdist.warranty,endoftime())) );

--  Nope, make it
      IF (NOT FOUND) THEN
        SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
        INSERT INTO itemloc
        ( itemloc_id, itemloc_itemsite_id,
          itemloc_location_id, itemloc_qty,
          itemloc_ls_id, itemloc_expiration,
          itemloc_warrpurc )
        VALUES
        ( _itemlocid, _itemlocdist.itemsiteid,
          _itemlocdist.sourceid, 0,
          _itemlocdist.lotserialid, _itemlocdist.expiration,
          _itemlocdist.warranty );
      END IF;

    ELSE
--  Yep, cache it
      _itemlocid = _itemlocdist.sourceid;

      IF (_itemlocid IS NOT NULL AND (SELECT count(itemloc_id) = 0 FROM itemloc WHERE itemloc_id=_itemlocid)) THEN
        RAISE EXCEPTION 'No record to distribute against. Someone else may have already distributed this record.';
      END IF;
    END IF;

--  Record the invdetail for this itemlocdist
    INSERT INTO invdetail
    ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
      invdetail_qty, invdetail_qty_before, invdetail_qty_after, invdetail_expiration, 
      invdetail_warrpurc )
    SELECT _itemlocdist.invhistid, itemloc_location_id, itemloc_ls_id,
           _itemlocdist.qty, itemloc_qty, (itemloc_qty + _itemlocdist.qty),
           itemloc_expiration,_itemlocdist.warranty
    FROM itemloc
    WHERE (itemloc_id=_itemlocid);

--  Update the parent invhist to indicate that it has invdetail records
    UPDATE invhist
    SET invhist_hasdetail=TRUE
    WHERE ((invhist_hasdetail=FALSE)
     AND (invhist_id=_itemlocdist.invhistid));

--  Update the itemloc_qty if its parent itemsite is not frozen
    IF (NOT _itemlocdist.itemsite_freeze) THEN
      UPDATE itemloc
      SET itemloc_qty = (itemloc_qty + _itemlocdist.qty)
      WHERE (itemloc_id=_itemlocid);

      PERFORM postInvHist(_itemlocdist.invhistid);

--  Handle reservation data
      IF ( (SELECT fetchMetricBool('EnableSOReservationsByLocation')) AND
           (_itemlocdist.qty < 0) ) THEN

--  If a shipment on a sales order, record reservation change before updating
--  so it can be reversed later if necessary
        IF (_itemlocdist.ordertype = 'SO') THEN
          INSERT INTO shipitemlocrsrv
          SELECT nextval('shipitemlocrsrv_shipitemlocrsrv_id_seq'),
            shipitem_id, itemloc_itemsite_id, itemloc_location_id,
            itemloc_ls_id, itemloc_expiration, itemloc_warrpurc,
            least(_itemlocdist.qty, itemlocrsrv_qty)
          FROM shipitem, itemloc
            JOIN itemlocrsrv ON (itemloc_id=itemlocrsrv_itemloc_id)
          WHERE ( (shipitem_invhist_id=_itemlocdist.invhistid)
            AND   (itemloc_id=_itemlocid)
            AND   (itemlocrsrv_source=_itemlocdist.ordertype)
            AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
        END IF;

--  Update the itemloc reservation
        UPDATE itemlocrsrv
        SET itemlocrsrv_qty = (itemlocrsrv_qty + _itemlocdist.qty)
        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
          AND   (itemlocrsrv_source_id=_itemlocdist.orderid) );
          
--  Delete reservation if fully distributed
        DELETE FROM itemlocrsrv
        WHERE ( (itemlocrsrv_itemloc_id=_itemlocid)
          AND   (itemlocrsrv_source=_itemlocdist.ordertype)
          AND   (itemlocrsrv_source_id=_itemlocdist.orderid)
          AND   (itemlocrsrv_qty=0) );
      END IF;
    END IF;

--  Adjust QOH if this itemlocdist is to/from a non-netable location
    IF ( SELECT (NOT location_netable)
         FROM itemloc, location
         WHERE ((itemloc_location_id=location_id)
          AND (itemloc_id=_itemlocid)) ) THEN

--  Record the invhist record for the netable->non-netable (or visaversa)
      INSERT INTO invhist
      ( invhist_itemsite_id,
        invhist_transtype, invhist_invqty,
        invhist_qoh_before, invhist_qoh_after,
        invhist_docnumber, invhist_comments,
        invhist_invuom, invhist_unitcost,
        invhist_costmethod, invhist_value_before, invhist_value_after,
        invhist_series )
      SELECT itemsite_id,
             'NN', (_itemlocdist.qty * -1),
             itemsite_qtyonhand, (itemsite_qtyonhand - _itemlocdist.qty),
             invhist_docnumber, invhist_comments,
             uom_name, stdCost(item_id),
             itemsite_costmethod, itemsite_value,
             (itemsite_value + (_itemlocdist.qty * -1 * CASE WHEN(itemsite_costmethod='A') THEN avgcost(itemsite_id)
                                                             ELSE stdCost(itemsite_item_id)
                                                        END)),
             _itemlocdist.series
      FROM item, itemsite, invhist, uom
      WHERE ( (itemsite_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (itemsite_controlmethod <> 'N')
       AND (itemsite_id=_itemlocdist.itemsiteid)
       AND (invhist_id=_itemlocdist.invhistid) );

--  Update the itemsite_qoh
      IF (NOT _itemlocdist.itemsite_freeze) THEN
        UPDATE itemsite
        SET itemsite_qtyonhand = (itemsite_qtyonhand - _itemlocdist.qty),
            itemsite_nnqoh = (itemsite_nnqoh + _itemlocdist.qty)
        FROM itemloc
        WHERE ((itemloc_itemsite_id=itemsite_id)
         AND (itemloc_id=_itemlocid));
      END IF;
    END IF;

--  Cache the running qty.
    _runningQty := _runningQty + _itemlocdist.qty;

--  Dene with the child itemlocdist, so delete it
    DELETE FROM itemlocdist
    WHERE (itemlocdist_id=_itemlocdist.itemlocdistid);

--  If the target itemloc is now at qty=0, delete it if its parent
--  itemsite is not frozen
    IF (NOT _itemlocdist.itemsite_freeze) THEN
      DELETE FROM itemloc
      WHERE ( (itemloc_qty=0)
       AND (itemloc_id=_itemlocid) );
    END IF;

  END LOOP;

--  If the running qty for the detailed distributions is the same as the
--  total qty to distribute indicated by the parent itemlocdist, then the
--  parent itemlocdist has been fully distributed and should be deleted.
  IF ( ( SELECT itemlocdist_qty
         FROM itemlocdist
         WHERE (itemlocdist_id=pItemlocdistid) ) = _runningQty) THEN
    DELETE FROM itemlocdist
    WHERE (itemlocdist_id=pItemlocdistid);
  ELSE
--  There is still some more qty to distribute in the parent itemlocdist.
--  Update the qty to distribute with the qty that has been distributed.
    UPDATE itemlocdist
    SET itemlocdist_qty = (itemlocdist_qty - _runningQty)
    WHERE (itemlocdist_id=pItemlocdistid);
  END IF;

  RETURN _distCounter;

END;

Function: public.distributevoucherline(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoucherId ALIAS FOR $1;
  pPoitemId ALIAS FOR $2;
  pCurrId ALIAS FOR $3;
  _count INTEGER;
  _costelemId INTEGER;
  _close BOOLEAN;
  _r RECORD;
  _qtyOrdered NUMERIC;
  _voitemId INTEGER;
  _taxtypeid INTEGER;

BEGIN

--  Make sure the P/O and Voucher are same currency

  SELECT COALESCE(COUNT(*),0) INTO _count
        FROM poitem JOIN pohead ON (pohead_id=poitem_pohead_id)
        WHERE ((poitem_id=pPoitemid)
        AND (pohead_curr_id=pCurrId));
  IF (_count = 0) THEN
        RETURN -3;
  END IF;

--  Validate and get cost element

        SELECT COALESCE(COUNT(*),0) INTO _count
                FROM itemcost, item, itemsite, poitem
                WHERE ((itemcost_item_id=item_id)
                AND (item_id=itemsite_item_id)
                AND (itemsite_id=poitem_itemsite_id)
                AND (poitem_id=pPoitemId));

        IF (_count > 1) THEN
                RETURN -5;
        ELSEIF (_count = 1) THEN
                SELECT itemcost_costelem_id INTO _costelemId
                        FROM itemcost, item, itemsite, poitem
                        WHERE ((itemcost_item_id=item_id)
                        AND (item_id=itemsite_item_id)
                        AND (itemsite_id=poitem_itemsite_id)
                        AND (poitem_id=pPoitemId));
        ELSE
                SELECT costelem_id INTO _costelemId
                        FROM costelem
                        WHERE (costelem_type='Material');
        END IF;


--  Clear previous distributions

        UPDATE recv SET recv_vohead_id=NULL, recv_voitem_id=NULL
                WHERE ((recv_vohead_id=pVoucherId)
                AND (recv_orderitem_id=pPoitemId)
		AND (recv_order_type='PO'));
        UPDATE poreject SET poreject_vohead_id=NULL, poreject_voitem_id=NULL
                WHERE ((poreject_vohead_id=pVoucherId)
                AND (poreject_poitem_id=pPoitemId));
        DELETE FROM vodist
                WHERE ((vodist_poitem_id=pPoitemId)
                AND (vodist_vohead_id=pVoucherId));
        DELETE FROM voitem
                WHERE ((voitem_poitem_id=pPoitemId)
                AND (voitem_vohead_id=pVoucherId));

--  Determine Line balances

        SELECT  COALESCE(SUM(qty_received),0) AS qty_received,
                COALESCE(SUM(qty_rejected),0) AS qty_rejected,
                COALESCE(SUM(qty_vouchered),0) AS qty_vouchered,
                round(COALESCE(SUM(balance),0),2) AS balance,
                round(COALESCE(SUM(freight),0),2) AS freight INTO _r
         FROM   (
                SELECT  recv_qty AS qty_received,
                        0 AS qty_rejected,
                        0 AS qty_vouchered,
                        (recv_qty * COALESCE(recv_purchcost, poitem_unitprice)) AS balance,
                        recv_freight AS freight
                FROM poitem JOIN recv ON ((recv_orderitem_id=poitem_id) AND
                                          (recv_order_type='PO'))
                WHERE ( (recv_vohead_id IS NULL)
                        AND (NOT recv_invoiced)
                        AND (recv_posted)
                        AND (poitem_id=pPoitemId) )

                UNION ALL

                SELECT  0 AS qty_received,
                        (poreject_qty) AS qty_rejected,
                        0 AS qty_vouchered,
                        (poreject_qty * -1 * COALESCE(recv_purchcost, poitem_unitprice)) AS balance,
                        0 AS freight
                FROM poitem JOIN poreject ON (poreject_poitem_id=poitem_id)
                            LEFT OUTER JOIN recv ON (recv_id=poreject_recv_id)
                WHERE ( (poreject_posted)
                        AND (poreject_vohead_id IS NULL)
                        AND (NOT poreject_invoiced)
                        AND (poitem_id=pPoitemId) )

                UNION ALL

                SELECT  0 AS qty_received,
                        0 AS qty_rejected,
                        voitem_qty AS qty_vouchered,
                        0 AS balance,
                        0 AS freight
                FROM voitem, poitem
                WHERE ( (voitem_poitem_id=pPoitemId)
                        AND (poitem_id=voitem_poitem_id) )
                ) AS data;

                SELECT poitem_qty_ordered INTO _qtyOrdered
                FROM poitem
                WHERE (poitem_id=pPoitemId);

        IF _r.balance < 0 THEN
                RETURN -4;
        ELSEIF ( ((_r.qty_received <> 0) OR (_r.qty_received <> 0)) AND (_r.qty_received - _r.qty_rejected = 0) ) THEN
                RETURN -2;
        ELSEIF ((_r.qty_received - _r.qty_rejected) = 0) THEN
                RETURN 0;
        END IF;

-- Determine whether to close P/O item

        IF (_r.qty_received -_r.qty_rejected + _r.qty_vouchered) >= _qtyOrdered THEN
                _close:=True;
        ELSE
                _close:=False;
        END IF;


-- Create distribution

        INSERT INTO vodist
                (vodist_poitem_id,vodist_vohead_id,vodist_costelem_id,vodist_amount,vodist_qty,vodist_expcat_id)
                VALUES (pPoitemId,pVoucherId,_costelemId,_r.balance,(_r.qty_received -_r.qty_rejected),-1);

-- Create voucher item
        SELECT poitem_taxtype_id INTO _taxtypeid
        FROM poitem
        WHERE (poitem_id=pPoitemId);

        SELECT NEXTVAL('voitem_voitem_id_seq') INTO _voitemId;

        INSERT INTO voitem (voitem_id,voitem_vohead_id,voitem_poitem_id,voitem_close,voitem_qty,voitem_freight, voitem_taxtype_id)
                VALUES (_voitemId,pVoucherId,pPoitemId,_close,(_r.qty_received -_r.qty_rejected),_r.freight, _taxtypeid);

-- Tag receipt records

        UPDATE recv
        SET recv_vohead_id=pVoucherId, recv_voitem_id=_voitemId
        WHERE ((recv_orderitem_id=pPoitemId)
	  AND  (recv_order_type='PO')
          AND  (recv_vohead_id IS NULL));

        UPDATE poreject
        SET poreject_vohead_id=pVoucherId,poreject_voitem_id=_voitemId
        WHERE ((poreject_poitem_id=pPoitemId)
        AND (NOT poreject_invoiced)
        AND (poreject_vohead_id IS NULL));


  RETURN 1;

END;

Function: public.dopostcosts(boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pMaterial ALIAS FOR $1;
  plowerMaterial ALIAS FOR $2;
  pdirectLabor ALIAS FOR $3;
  plowerDirectLabor ALIAS FOR $4;
  poverhead ALIAS FOR $5;
  plowerOverhead ALIAS FOR $6;
  pmachOverhead ALIAS FOR $7;
  plowerMachOverhead ALIAS FOR $8;
  pUser ALIAS FOR $9;
  plowerUser ALIAS FOR $10;
  prollUp ALIAS FOR $11;
  _item RECORD;
  _result INTEGER := 0;

BEGIN

  PERFORM resetLowLevelCode(-1);

  FOR _item IN SELECT costUpdate_item_id
            FROM costUpdate
            ORDER BY costUpdate_lowlevel_code DESC LOOP
    PERFORM doPostCosts(_item.costUpdate_item_id, FALSE,
		       pMaterial, plowerMaterial, pdirectLabor,
		       plowerDirectLabor, poverhead, plowerOverhead,
		       pmachOverhead, plowerMachOverhead,
		       puser, plowerUser, prollUp);
  END LOOP;

  RETURN _result;

END;
 

Function: public.dopostcosts(integer, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pItemId ALIAS FOR $1;
  pResetLowLevel ALIAS FOR $2;
  pMaterial ALIAS FOR $3;
  plowerMaterial ALIAS FOR $4;
  pdirectLabor ALIAS FOR $5;
  plowerDirectLabor ALIAS FOR $6;
  poverhead ALIAS FOR $7;
  plowerOverhead ALIAS FOR $8;
  pmachOverhead ALIAS FOR $9;
  plowerMachOverhead ALIAS FOR $10;
  pUser ALIAS FOR $11;
  plowerUser ALIAS FOR $12;
  prollUp ALIAS FOR $13;
  _itemcost RECORD;
  _result INTEGER;

BEGIN

    IF (pResetLowLevel) THEN
	PERFORM resetLowLevelCode(pItemId);
    END IF;

    FOR _itemcost IN SELECT itemcost_id, costelem_sys, costelem_type,
			    itemcost_lowlevel,
			    costUpdate_lowlevel_code, costUpdate_item_type
            FROM itemcost, costelem, costUpdate
            WHERE itemcost_item_id = pItemId
	      AND costUpdate_item_id = itemcost_item_id
              AND itemcost_costelem_id = costelem_id LOOP
      IF (NOT _itemcost.costelem_sys) THEN
        IF ( (pUser) AND ( NOT _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
        IF ( (plowerUser) AND ( _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
      END IF;

      IF (_itemcost.costelem_type = 'Material') THEN
        IF ( (pMaterial) AND ( NOT _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
        IF ( (plowerMaterial) AND ( _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
      END IF;

      IF (_itemcost.costelem_type = 'Direct Labor') THEN
        IF ( (pdirectLabor) AND ( NOT _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
        IF ( (plowerDirectLabor) AND ( _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
      END IF;

      IF (_itemcost.costelem_type = 'Overhead') THEN
        IF ( (poverhead) AND ( NOT _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
        IF ( (plowerOverhead) AND ( _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
      END IF;

      IF (_itemcost.costelem_type = 'Machine Overhead') THEN
        IF ( (pmachOverhead) AND ( NOT _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
        IF ( (plowerMachOverhead) AND ( _itemcost.itemcost_lowlevel) ) THEN
          PERFORM postCost(_itemcost.itemcost_id);
          _result := _result + 1;
        END IF;
      END IF;

    END LOOP;

    IF (prollUp) THEN    
      PERFORM rollUpStandardCost(pItemId);
      _result := _result + 1;
    END IF;

    RETURN _result;

END;
 

Function: public.doupdatecosts(boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  plowerMaterial ALIAS FOR $1;
  pdirectLabor ALIAS FOR $2;
  plowerDirectLabor ALIAS FOR $3;
  poverhead ALIAS FOR $4;
  plowerOverhead ALIAS FOR $5;
  pmachOverhead ALIAS FOR $6;
  plowerMachOverhead ALIAS FOR $7;
  plowerUser ALIAS FOR $8;
  prollUp ALIAS FOR $9;

BEGIN
  RETURN doUpdateCosts(plowerMaterial, pdirectLabor, plowerDirectLabor,
		       poverhead, plowerOverhead, pmachOverhead,
		       plowerMachOverhead, plowerUser, prollUp, TRUE);
END;

Function: public.doupdatecosts(boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  plowerMaterial ALIAS FOR $1;
  pdirectLabor ALIAS FOR $2;
  plowerDirectLabor ALIAS FOR $3;
  poverhead ALIAS FOR $4;
  plowerOverhead ALIAS FOR $5;
  pmachOverhead ALIAS FOR $6;
  plowerMachOverhead ALIAS FOR $7;
  plowerUser ALIAS FOR $8;
  prollUp ALIAS FOR $9;
  pActual ALIAS FOR $10;
  _item RECORD;
  _bom RECORD;
  _result INTEGER := 0;

BEGIN

  PERFORM resetLowLevelCode(-1);

  FOR _item IN SELECT costUpdate_item_id
            FROM costUpdate
            ORDER BY costUpdate_lowlevel_code DESC LOOP
    PERFORM doUpdateCosts(_item.costUpdate_item_id, false, plowerMaterial,
		  pdirectLabor, plowerDirectLabor, poverhead, plowerOverhead,
		  pmachOverhead, plowerMachOverhead, plowerUser, prollUp,
		  pActual);
  END LOOP;

  RETURN _result;

END;
 

Function: public.doupdatecosts(integer, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pItemId ALIAS FOR $1;
  pResetLowLevel ALIAS FOR $2;
  plowerMaterial ALIAS FOR $3;
  pdirectLabor ALIAS FOR $4;
  plowerDirectLabor ALIAS FOR $5;
  poverhead ALIAS FOR $6;
  plowerOverhead ALIAS FOR $7;
  pmachOverhead ALIAS FOR $8;
  plowerMachOverhead ALIAS FOR $9;
  plowerUser ALIAS FOR $10;
  prollUp ALIAS FOR $11;

BEGIN
    RETURN doUpdateCosts(pItemId, pResetLowLevel, plowerMaterial, pdirectLabor,
			 plowerDirectLabor, poverhead, plowerOverhead,
			 pmachOverhead, plowerMachOverhead, plowerUser, prollUp,
			 TRUE);
END;

Function: public.doupdatecosts(integer, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pItemId ALIAS FOR $1;
  pResetLowLevel ALIAS FOR $2;
  plowerMaterial ALIAS FOR $3;
  pdirectLabor ALIAS FOR $4;
  plowerDirectLabor ALIAS FOR $5;
  poverhead ALIAS FOR $6;
  plowerOverhead ALIAS FOR $7;
  pmachOverhead ALIAS FOR $8;
  plowerMachOverhead ALIAS FOR $9;
  plowerUser ALIAS FOR $10;
  prollUp ALIAS FOR $11;
  pUpdateActual ALIAS FOR $12;
  _item RECORD;
  _bom RECORD;
  _result INTEGER := 0;
  _resultFromReset INTEGER;
  _counterNum INTEGER;
  _feedBackNum INTEGER;

BEGIN

    IF (pResetLowLevel) THEN
	PERFORM resetLowLevelCode(pItemId);
    END IF;

    SELECT costUpdate_item_id AS item_id, costUpdate_item_type AS item_type
	INTO _item
    FROM costUpdate
    WHERE costUpdate_item_id = pItemId;

    IF ((plowerMaterial) AND ((_item.item_type <> 'P') AND (_item.item_type <> 'O'))) THEN    
      PERFORM updateSorACost(_item.item_id, 'Material', TRUE, lowerCost(_item.item_id, 'Material', pUpdateActual), pUpdateActual);
    END IF;

    IF (pdirectLabor) THEN    
      PERFORM updateSorACost(_item.item_id, 'Direct Labor', FALSE, xtmfg.directLaborCost(_item.item_id), pUpdateActual);
    END IF;

    IF (plowerDirectLabor) THEN    
      PERFORM updateSorACost(_item.item_id, 'Direct Labor', TRUE, lowerCost(_item.item_id, 'Direct Labor', pUpdateActual), pUpdateActual);
    END IF;

    IF (poverhead) THEN    
      PERFORM updateSorACost(_item.item_id, 'Overhead', FALSE, xtmfg.overheadCost(_item.item_id), pUpdateActual);
    END IF;

    IF (plowerOverhead) THEN    
      PERFORM updateSorACost(_item.item_id, 'Overhead', TRUE, lowerCost(_item.item_id, 'Overhead', pUpdateActual), pUpdateActual);
    END IF;

    IF (pmachOverhead) THEN    
      PERFORM updateSorACost(_item.item_id, 'Machine Overhead', FALSE, xtmfg.machineOverheadCost(_item.item_id), pUpdateActual);
    END IF;

    IF (plowerMachOverhead) THEN    
      PERFORM updateSorACost(_item.item_id, 'Machine Overhead', TRUE, lowerCost(_item.item_id, 'Machine Overhead', pUpdateActual), pUpdateActual);
    END IF;

    IF (plowerUser) THEN    
      PERFORM updateLowerUserCosts(_item.item_id, pUpdateActual);
    END IF;

    IF (prollUp) THEN    
      PERFORM rollUpSorACost(_item.item_id, pUpdateActual);
    END IF;

    RETURN _result;

END;
 

Function: public.dropifexists(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN dropIfExists($1, $2, 'public');
END;

Function: public.dropifexists(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN dropIfExists($1, $2, $3, false);
END;

Function: public.dropifexists(text, text, text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pType         ALIAS FOR $1;
  pObject       ALIAS FOR $2;
  pSchema       ALIAS FOR $3;
  pCascade      ALIAS FOR $4;
  _table	TEXT;
  _query	TEXT;
BEGIN
  IF (UPPER(pType) = 'INDEX') THEN
    _query = 'DROP INDEX ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(pObject));
    
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_object OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSEIF (UPPER(pType) = 'TABLE') THEN
    _query = 'DROP TABLE ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(pObject)); 
    
    IF (pCascade) THEN
      _query = _query || ' CASCADE';
    END IF;

    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_table OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'VIEW') THEN
    _query = 'DROP VIEW ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(pObject));

    IF (pCascade) THEN
      _query = _query || ' CASCADE';
    END IF;
    
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_table OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'TRIGGER') THEN
    SELECT relname INTO _table
    FROM pg_trigger, pg_class
    WHERE ((tgrelid=pg_class.oid)
      AND  (UPPER(tgname)=UPPER(pObject)));
    IF (NOT FOUND) THEN
      _table := '[no table]';
    END IF;

    _query = 'DROP TRIGGER ' || quote_ident(LOWER(pObject)) ||
	     ' ON ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(_table));
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_object THEN
		RETURN 0;
	      WHEN undefined_table OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'FUNCTION') THEN
    _query = 'DROP FUNCTION ' || (LOWER(pSchema)) || '.' ||
                                   (LOWER(pObject));
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_object OR undefined_function OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'CONSTRAINT') THEN
    IF( (SELECT count(*)
           FROM pg_constraint, pg_class, pg_namespace
          WHERE((conrelid=pg_class.oid)
            AND (connamespace=pg_namespace.oid)
            AND (conname=pObject)
            AND (nspname=pSchema))
         ) > 1 ) THEN
      RAISE EXCEPTION 'dropIfExists called on constraint name that matches more than 1 constraint.';
    END IF;
    SELECT relname INTO _table
    FROM pg_constraint, pg_class, pg_namespace
    WHERE ((conrelid=pg_class.oid)
      AND  (connamespace=pg_namespace.oid)
      AND  (conname=pObject)
      AND  (nspname=pSchema));
    IF (NOT FOUND) THEN
      RETURN 0;
    END IF;
    _query = 'ALTER TABLE ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(_table))
             || ' DROP CONSTRAINT ' || quote_ident(LOWER(pObject));
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_table OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'SCHEMA') THEN
    _query = 'DROP SCHEMA ' || quote_ident(LOWER(pObject));
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN invalid_schema_name THEN
                RETURN 0;
              WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSIF (UPPER(pType) = 'TYPE') THEN
    _query = 'DROP TYPE ' || quote_ident(LOWER(pSchema)) || '.' ||
                               quote_ident(LOWER(pObject));
    IF (pCascade) THEN
      _query = _query || ' CASCADE';
    END IF;
    
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_object OR invalid_schema_name THEN
                RETURN 0;
              WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSE
    RAISE EXCEPTION 'dropIfExists(%, %): unknown pType %', pType, pObject, pType;
  END IF;

  RETURN 1;

END;

Function: public.dropifexists(text, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pType         ALIAS FOR $1;
  pObject       ALIAS FOR $2;
  pSchema       ALIAS FOR $3;
  pRelation     ALIAS FOR $4;
  _table        TEXT;
  _query	TEXT;
BEGIN
  IF (UPPER(pType) = 'CONSTRAINT') THEN
    SELECT relname INTO _table
    FROM pg_constraint, pg_class, pg_namespace
    WHERE ((conrelid=pg_class.oid)
      AND  (connamespace=pg_namespace.oid)
      AND  (conname=pObject)
      AND  (relname=pRelation)
      AND  (nspname=pSchema));
    IF (NOT FOUND) THEN
      RETURN 0;
    END IF;
    _query = 'ALTER TABLE ' || quote_ident(LOWER(pSchema)) || '.' || quote_ident(LOWER(pRelation))
             || ' DROP CONSTRAINT ' || quote_ident(LOWER(pObject));
    BEGIN
      EXECUTE _query;
    EXCEPTION WHEN undefined_table OR invalid_schema_name THEN
		RETURN 0;
	      WHEN OTHERS THEN RAISE EXCEPTION '% %', SQLSTATE, SQLERRM;
    END;

  ELSE
    RAISE EXCEPTION 'dropIfExists(%, %, %, %): pType % is not supported when relation is specified', pType, pObject, pSchema, pRelation, pType;
  END IF;

  RETURN 1;
END;

Function: public.dropstdopntable()

Returns: boolean

Language: PLPGSQL

BEGIN
  IF((SELECT metric_value != 'Manufacturing' FROM metric WHERE metric_name = 'Application')) THEN
    PERFORM dropIfExists('TABLE', 'stdopn');
    RETURN true;
  END IF;
  RETURN false;
END;

Function: public.editccnumber(text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCcardnum ALIAS FOR $1;
  pCcardtype ALIAS FOR $2;
  card_length INTEGER;
  card_valid boolean := false;
  starting_digits TEXT;
  _sum INTEGER := 0;
  _digit INTEGER := 0;
  _timesTwo BOOLEAN := false;
BEGIN

-- Check the card type
  IF (pCcardtype NOT IN ('M', 'V', 'A', 'D')) THEN
-- Unknown Card Type
   RETURN -1;
  END IF;

  card_length := length(pCcardnum);

-- Process Master Card Checking length
-- Process Master Card Starting digits
  IF (pCcardtype = 'M') THEN
    IF (card_length != 16) THEN
-- Bad Card Length Card Type
      RETURN -2;
    END IF;
    starting_digits := substr(pCcardnum, 1, 2);
    IF (starting_digits < '51' OR starting_digits > '55') THEN
-- Bad Starting digits
      RETURN -6;
    END IF;
  END IF;

-- Process Visa Card Checking length
-- Process Visa Card Starting digits
  IF (pCcardtype = 'V') THEN
    IF (card_length != 13 AND card_length != 16) THEN
-- Bad Card Length Card Type
      RETURN -3;
    END IF;
    starting_digits := substr(pCcardnum, 1, 1);
    IF (starting_digits != '4') THEN
-- Bad Starting digits
      RETURN -7;
    END IF;
  END IF;

-- Process American Express Card Checking length
-- Process American Express Card Starting digits
  IF (pCcardtype = 'A') THEN
    IF (card_length != 15) THEN
-- Bad Card Length Card Type
      RETURN -4;
    END IF;
    starting_digits := substr(pCcardnum, 1, 2);
    IF (starting_digits != '34' AND starting_digits != '37') THEN
-- Bad Starting digits
      RETURN -8;
    END IF;
  END IF;

-- Process Discover Card Checking length
-- Process Discover Card Starting digits
  IF (pCcardtype = 'D') THEN
    IF (card_length != 16) THEN
-- Bad Card Length Card Type
      RETURN -5;
    END IF;
    starting_digits := substr(pCcardnum, 1, 4);
    IF (starting_digits != '6011') THEN
-- Bad Starting digits
      RETURN -9;
    END IF;
  END IF;

-- Now comes the fun part of doing the "check" for the check sum
-- perform a luhn checksum
  FOR i IN REVERSE card_length .. 1 LOOP
    _digit := int4(substr(pCcardnum, i, 1));
    IF (_timesTwo) THEN
      _digit := _digit * 2;
      IF (_digit > 9) THEN
        _digit := _digit - 9;
      END IF;
    END IF;
    _sum := _sum + _digit;
    _timesTwo := NOT _timesTwo;
  END LOOP;

  IF (mod(_sum, 10) != 0) THEN
    RETURN -10;
  END IF;

  RETURN 0; -- No Error

END;

Function: public.enablepackage(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgheadid    ALIAS FOR $1;
  _pkgname      TEXT;

BEGIN
  SELECT pkghead_name INTO _pkgname
  FROM pkghead
  WHERE (pkghead_id=ppkgheadid);
  IF (NOT FOUND) THEN
    RETURN -2;
  END IF;

  RETURN enablePackage(_pkgname);
END;

Function: public.enablepackage(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgname  ALIAS FOR $1;
  _i        INTEGER := 0;
  _tabs     TEXT[] := ARRAY['cmd',  'cmdarg', 'image',  'metasql',
                            'priv', 'report', 'script', 'uiform'];

BEGIN
  IF (version() < 'PostgreSQL 8.2') THEN
    RETURN -1;
  END IF;

  FOR _i IN ARRAY_LOWER(_tabs,1)..ARRAY_UPPER(_tabs,1) LOOP
    EXECUTE 'ALTER TABLE ' || ppkgname || '.pkg' || _tabs[_i] ||
            ' INHERIT public.' || _tabs[_i] || ';';
  END LOOP;

  RETURN 0;
END;

Function: public.encrypt(bytea, bytea, text)

Returns: bytea

Language: C

pg_encrypt

Function: public.encrypt_iv(bytea, bytea, bytea, text)

Returns: bytea

Language: C

pg_encrypt_iv

Function: public.endoftime()

Returns: date

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT DATE('2100-01-01') as result;

Function: public.entercount(integer, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcntid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pComments ALIAS FOR $3;
BEGIN

  UPDATE invcnt
  SET invcnt_qoh_after = pQty,
      invcnt_comments = CASE WHEN ( (LENGTH(invcnt_comments) = 0) AND
                                    (LENGTH(pComments) > 0) ) THEN pComments
                             WHEN (LENGTH(pComments) > 0) THEN (invcnt_comments || E'\n' || pComments)
                             ELSE invcnt_comments
                        END,
      invcnt_cntdate = CURRENT_TIMESTAMP,
      invcnt_cnt_username = getEffectiveXtUser()
  WHERE (invcnt_id=pInvcntid);

  RETURN 0;
END;

Function: public.enterporeceipt(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterReceipt('PO', $1, $2, 0.0, '', NULL, NULL);
END;

Function: public.enterporeceipt(integer, numeric, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterPoReceipt('PO', $1, $2, $3, $4, NULL, NULL);
END;

Function: public.enterporeceipt(integer, numeric, numeric, text, integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterReceipt('PO', $1, $2, $3, $4, $5, $6);
END;

Function: public.enterporeceipt(integer, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterPoReceipt('PO', $1, $2, 0.0, $3, NULL, NULL);
END;

Function: public.enterporeturn(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterPoReturn($1, $2, $3, NULL);
END;

Function: public.enterporeturn(integer, numeric, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoitemid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pRjctcodeid ALIAS FOR $3;
  pRecvid ALIAS FOR $4;
  _porejectid INTEGER;

BEGIN

  SELECT NEXTVAL('poreject_poreject_id_seq') INTO _porejectid;

  INSERT INTO poreject
  ( poreject_id, poreject_date, poreject_ponumber, poreject_poitem_id, poreject_trans_username,
    poreject_agent_username, poreject_itemsite_id,
    poreject_vend_id, poreject_vend_item_number, poreject_vend_item_descrip, poreject_vend_uom,
    poreject_qty, poreject_rjctcode_id, poreject_posted, poreject_invoiced, poreject_recv_id )
  SELECT _porejectid, CURRENT_TIMESTAMP, pohead_number, poitem_id, getEffectiveXtUser(),
         pohead_agent_username, poitem_itemsite_id,
         pohead_vend_id, poitem_vend_item_number, poitem_vend_item_descrip, poitem_vend_uom,
         pQty, pRjctcodeid, FALSE, FALSE, pRecvid
  FROM poitem JOIN pohead ON (pohead_id=poitem_pohead_id)
  WHERE (poitem_id=pPoitemid);

  RETURN _porejectid;

END;

Function: public.enterreceipt(text, integer, numeric, numeric, text, integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN enterReceipt($1, $2, $3, $4, $5, $6, $7, NULL);
END;

Function: public.enterreceipt(text, integer, numeric, numeric, text, integer, date, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  porderitemid	ALIAS FOR $2;
  pQty		ALIAS FOR $3;
  pFreight	ALIAS FOR $4;
  pNotes	ALIAS FOR $5;
  pcurrid	ALIAS FOR $6;	-- NULL is handled by SELECT ... INTO _o
  precvdate	ALIAS FOR $7;	-- NULL is handled by INSERT INTO recv
  pRecvCost	ALIAS FOR $8;
  _timestamp    TIMESTAMP;
  _o		RECORD;
  _recvid	INTEGER;
  _warehouseid 	INTEGER;
  _recvcost	NUMERIC;

BEGIN
  IF(precvdate IS NULL OR precvdate = CURRENT_DATE) THEN
    _timestamp := CURRENT_TIMESTAMP;
  ELSE
    _timestamp := precvdate;
  END IF;
  SELECT NEXTVAL('recv_recv_id_seq') INTO _recvid;

  DELETE FROM recv
  WHERE ((NOT recv_posted)
    AND  (recv_order_type=pordertype)
    AND  (recv_orderitem_id=porderitemid) );

  IF (pQty > 0) THEN
    IF (pordertype='PO') THEN
      SELECT pohead_number AS orderhead_number,
  	   poitem_id AS orderitem_id,
	   pohead_agent_username AS orderhead_agent_username,
	   CASE WHEN (poitem_itemsite_id = -1) THEN NULL
		ELSE poitem_itemsite_id
	   END AS itemsite_id,
	   vend_id,
	   COALESCE(poitem_vend_item_number, '') AS vend_item_number,
	   COALESCE(poitem_vend_item_descrip, '') AS vend_item_descrip,
	   COALESCE(poitem_vend_uom, '') AS vend_uom,
	   poitem_duedate AS duedate,
	   poitem_unitprice AS orderitem_unitcost,
	   pohead_curr_id AS orderitem_unitcost_curr_id,
	   pohead_curr_id AS freight_curr_id,
	   poitem_rlsd_duedate AS rlsd_duedate INTO _o
        FROM pohead
          JOIN poitem ON (pohead_id=poitem_pohead_id)
          JOIN vendinfo ON (pohead_vend_id=vend_id)
        WHERE (poitem_id=porderitemid);
        
    ELSIF (pordertype='RA') THEN
       SELECT rahead_number AS orderhead_number,
  	   raitem_id AS orderitem_id,
	   ''::text AS orderhead_agent_username,
	   raitem_itemsite_id AS itemsite_id,
	   NULL::integer AS vend_id,
	   ''::text AS vend_item_number,
	   ''::text AS vend_item_descrip,
	   ''::text AS vend_uom,
	   raitem_scheddate AS duedate,
	   raitem_unitprice AS orderitem_unitcost,
	   rahead_curr_id AS orderitem_unitcost_curr_id,
	   rahead_curr_id AS freight_curr_id,
           raitem_scheddate AS rlsd_duedate INTO _o
        FROM rahead
          JOIN raitem ON (rahead_id=raitem_rahead_id)
        WHERE (raitem_id=porderitemid);
        
    ELSIF (pordertype='TO') THEN
         SELECT tohead_number AS orderhead_number,
  	   toitem_id AS orderitem_id,
	   tohead_agent_username AS orderhead_agent_username,
	   itemsite_id,
	   NULL::integer AS vend_id,
	   ''::text AS vend_item_number,
	   ''::text AS vend_item_descrip,
	   ''::text AS vend_uom,
	   toitem_duedate AS duedate,
	   toitem_stdcost AS orderitem_unitcost,
	   baseCurrId() AS orderitem_unitcost_curr_id,
	   toitem_freight_curr_id AS freight_curr_id,
           toitem_duedate AS rlsd_duedate INTO _o
        FROM itemsite, tohead
          JOIN toitem ON (tohead_id=toitem_tohead_id)
        WHERE ((toitem_id=porderitemid)
          AND  (tohead_dest_warehous_id=itemsite_warehous_id)
          AND  (toitem_item_id=itemsite_item_id));
    END IF;

    --Make sure user has site privileges
     IF ((FOUND) AND (_o.itemsite_id IS NOT NULL)) THEN
       SELECT warehous_id INTO _warehouseid
       FROM itemsite,site()
       WHERE ((itemsite_id=_o.itemsite_id)
         AND (warehous_id=itemsite_warehous_id));
          
       IF (NOT FOUND) THEN
         RETURN 0;
        END IF;
      END IF;   

    --Make sure we aren't trying to receive a Kit
    IF ((FOUND) AND (_o.itemsite_id IS NOT NULL)) THEN
      IF (SELECT (item_type='K')
          FROM itemsite, item
          WHERE ((itemsite_id=_o.itemsite_id)
            AND  (item_id=itemsite_item_id))) THEN
        RETURN 0;
      END IF;
    END IF;   

    IF (NOT FOUND) THEN
      RETURN -1;
    END IF;

    -- default to orderitem_unitcost if recv_purchcost is not specified
    IF(pRecvCost IS NULL) THEN
      _recvcost := _o.orderitem_unitcost;
    ELSE
      _recvcost := pRecvCost;
    END IF;

    INSERT INTO recv
    ( recv_id, recv_date,
      recv_order_number, recv_order_type, recv_orderitem_id,
      recv_trans_usr_name, recv_agent_username, recv_itemsite_id,
      recv_vend_id, recv_vend_item_number, recv_vend_item_descrip,
      recv_vend_uom, recv_qty, recv_duedate,
      recv_purchcost, recv_purchcost_curr_id,
      recv_notes, recv_freight, recv_freight_curr_id, recv_rlsd_duedate
    ) VALUES (
      _recvid, _timestamp,
      _o.orderhead_number, pordertype, _o.orderitem_id::INTEGER,
      getEffectiveXtUser(), _o.orderhead_agent_username, _o.itemsite_id::INTEGER,
      _o.vend_id::INTEGER, _o.vend_item_number, _o.vend_item_descrip,
      _o.vend_uom, pQty, _o.duedate,
      _recvcost, _o.orderitem_unitcost_curr_id::INTEGER,
      pNotes, pFreight, _o.freight_curr_id::INTEGER, _o.rlsd_duedate);
  END IF;

  RETURN _recvid;

END;

Function: public.expirecreditcard(integer, bytea)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCust ALIAS FOR $1;
  pKey ALIAS FOR $2;
  num_updated INTEGER;
  cc_year INTEGER;
  cc_month INTEGER;
  cc_year_t TEXT;
  cc_month_t TEXT;
  _dr RECORD;
  _cc RECORD;
  bf TEXT;

BEGIN

  num_updated := 0;
  bf := 'bf';

  select cast(date_part('year', CURRENT_DATE) AS INTEGER) AS check_year, cast(date_part('month', CURRENT_DATE) AS INTEGER) AS check_month INTO _dr;

  FOR _cc IN SELECT ccard_id, 
                    decrypt(setbytea(ccard_month_expired), setbytea(pKey), 'bf') AS ccard_month_expired,
                    decrypt(setbytea(ccard_year_expired), setbytea(pKey), 'bf') AS ccard_year_expired
      FROM ccard
      WHERE ( (ccard_cust_id=pCust)
        AND   (ccard_active) ) LOOP

      SELECT formatbytea(_cc.ccard_month_expired) INTO cc_month_t;
      SELECT formatbytea(_cc.ccard_year_expired) INTO cc_year_t;
      SELECT cast(cc_month_t AS INTEGER) INTO cc_month;
      SELECT cast(cc_year_t AS INTEGER) INTO cc_year;

      IF (cc_year < _dr.check_year) THEN
--  We have an expired card
        UPDATE ccard set ccard_active = FALSE where ccard_id = _cc.ccard_id;
        num_updated := num_updated + 1;
      ELSIF (cc_year = _dr.check_year AND cc_month < _dr.check_month) THEN
--  We have an expired card
        UPDATE ccard set ccard_active = FALSE where ccard_id = _cc.ccard_id;
        num_updated := num_updated + 1;
      END IF;

  END LOOP;

  RETURN num_updated;

END;

Function: public.explodebom(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pParentid ALIAS FOR $2;
  pLevel ALIAS FOR $3;
  _revid INTEGER;

BEGIN

  SELECT getActiveRevId('BOM',pItemid) INTO _revid;

  RETURN explodeBOM(pItemid, _revid, pParentid, pLevel);

END;

Function: public.explodebom(integer, integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  pParentid ALIAS FOR $3;
  pLevel ALIAS FOR $4;
  _bomworkid INTEGER;
  _level INTEGER;
  _p RECORD;
  _r RECORD;
  _temp TEXT;

BEGIN

  _level := (pLevel + 1);

--  Cache some parameters about the parent
  SELECT bomwork_item_id, bomwork_set_id, bomwork_qtyreq,
         bomwork_seqnumber, bomwork_effective, bomwork_expires INTO _p
  FROM bomwork
  WHERE (bomwork_id=pParentid);

--  Step through all of the components of the parent component
  FOR _r IN SELECT bomitem.*,
                   item_id,
                   (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyfxd) AS qtyfxd,
                   (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyper) AS qtyper,
                   CASE WHEN (_p.bomwork_effective > bomitem_effective) THEN _p.bomwork_effective
                        ELSE bomitem_effective
                   END AS effective,
                   CASE WHEN (_p.bomwork_expires < bomitem_expires) THEN _p.bomwork_expires
                        ELSE bomitem_expires
                   END AS expires,
                   stdcost(item_id, bomitem_id) AS standardcost, actcost(item_id, bomitem_id) AS actualcost
  FROM bomitem(pItemid, pRevisionid), item
  WHERE ( (bomitem_item_id=item_id)
  AND (bomitem_expires > _p.bomwork_effective) ) LOOP

--  Insert the current component and some bomitem parameters into the bomwork set
    SELECT NEXTVAL('bomwork_bomwork_id_seq') INTO _bomworkid;
    INSERT INTO bomwork
    ( bomwork_id, bomwork_set_id, bomwork_parent_id, bomwork_level,
      bomwork_parent_seqnumber, bomwork_seqnumber,
      bomwork_item_id, bomwork_createwo, bomwork_qtyreq,
      bomwork_qtyfxd, bomwork_qtyper, bomwork_scrap, bomwork_issuemethod,
      bomwork_effective, bomwork_expires,
      bomwork_stdunitcost, bomwork_actunitcost, 
      bomwork_notes, bomwork_ref,
      bomwork_bomitem_id, bomwork_ecn )
    VALUES
    ( _bomworkid, _p.bomwork_set_id, pParentid, _level,
      _p.bomwork_seqnumber, _r.bomitem_seqnumber,
      _r.item_id, _r.bomitem_createwo, (_p.bomwork_qtyreq * _r.qtyper + _r.qtyfxd),
      _r.qtyfxd, _r.qtyper, _r.bomitem_scrap, _r.bomitem_issuemethod,
      _r.effective, _r.expires,
      _r.standardcost, _r.actualcost,
      _r.bomitem_notes, _r.bomitem_ref,
      _r.bomitem_id, _r.bomitem_ecn );

--  Recursively repeat for this component's components
    PERFORM explodeBOM(_r.item_id, _bomworkid, _level);
  END LOOP;

  RETURN 1;

END;

Function: public.explodekit(integer, integer, integer, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  pLinenumber ALIAS FOR $2;
  pSubnumber ALIAS FOR $3;
  pItemsiteid ALIAS FOR $4;
  pQty ALIAS FOR $5;
BEGIN
  RETURN explodeKit(pSoheadid, pLinenumber, pSubnumber, pItemsiteid, pQty, CURRENT_DATE, NULL);
END;

Function: public.explodekit(integer, integer, integer, integer, numeric, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  pLinenumber ALIAS FOR $2;
  pSubnumber ALIAS FOR $3;
  pItemsiteid ALIAS FOR $4;
  pQty ALIAS FOR $5;
  pScheddate ALIAS FOR $6;
  pPromdate ALIAS FOR $7;
BEGIN
  RETURN explodeKit(pSoheadid, pLinenumber, pSubnumber, pItemsiteid, pQty, CURRENT_DATE, NULL, '');
END;

Function: public.explodekit(integer, integer, integer, integer, numeric, date, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  pLinenumber ALIAS FOR $2;
  pSubnumber ALIAS FOR $3;
  pItemsiteid ALIAS FOR $4;
  pQty ALIAS FOR $5;
  pScheddate ALIAS FOR $6;
  pPromdate ALIAS FOR $7;
  pMemo ALIAS FOR $8;
  _subnumber INTEGER := COALESCE(pSubnumber,0);
  _revid INTEGER;
  _itemid INTEGER;
  _warehousid INTEGER;
  _item RECORD;
  _type TEXT;
  _coitemid INTEGER;
  _count INTEGER;
  _orderid INTEGER := 0;
  _itemsrcid INTEGER;
BEGIN

  SELECT getActiveRevId('BOM',itemsite_item_id), itemsite_warehous_id, itemsite_item_id
    INTO _revid, _warehousid, _itemid
    FROM itemsite
   WHERE(itemsite_id=pItemsiteid);
  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'No Item Site for the specified line was found.';
  END IF;

  FOR _item IN
  SELECT bomitem_id, 
         itemsite_id,
         itemsite_warehous_id,
         COALESCE((itemsite_active AND item_active), false) AS active,
         COALESCE((itemsite_sold AND item_sold), false) AS sold,
         item_id,
         item_type,
         item_price_uom_id,
         itemsite_createsopr,itemsite_createwo,itemsite_createsopo, itemsite_dropship,
         bomitem_uom_id,
         itemuomtouomratio(item_id, bomitem_uom_id, item_inv_uom_id) AS invuomratio,
         roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id),(bomitem_qtyfxd + bomitem_qtyper * pQty) * (1 + bomitem_scrap)) AS qty
    FROM bomitem JOIN item ON (item_id=bomitem_item_id)
                  LEFT OUTER JOIN itemsite ON ((itemsite_item_id=item_id) AND (itemsite_warehous_id=_warehousid))
   WHERE((bomitem_parent_item_id=_itemid)
     AND (bomitem_rev_id=_revid)
     AND (CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1)))
   ORDER BY bomitem_seqnumber LOOP
    IF (NOT _item.active) THEN
      RAISE EXCEPTION 'One or more of the components for the kit is inactive for the selected item site.';
    ELSIF (NOT _item.sold) THEN
      RAISE EXCEPTION 'One or more of the components for the kit is not sold for the selected item site.';
    ELSIF (_item.item_type='F') THEN
      SELECT explodeKit(pSoheadid, pLinenumber, _subnumber, _item.itemsite_id, _item.qty)
        INTO _subnumber;
    ELSE
      IF (_item.itemsite_createsopr) THEN
        _type := 'R';
      ELSIF (_item.itemsite_createsopo) THEN
        _type := 'P';
      ELSIF (_item.itemsite_createwo) THEN
        _type := 'W';
      ELSE
        _type := NULL;
      END IF;
      _subnumber := _subnumber + 1;
      _coitemid = nextval('coitem_coitem_id_seq');
      raise notice 'coitem id: %',_coitemid;
      INSERT INTO coitem
            (coitem_id, coitem_cohead_id,
             coitem_linenumber, coitem_subnumber,
             coitem_itemsite_id, coitem_status,
             coitem_scheddate, coitem_promdate,
             coitem_qtyord, coitem_qty_uom_id, coitem_qty_invuomratio,
             coitem_qtyshipped, coitem_qtyreturned,
             coitem_unitcost, coitem_custprice,
             coitem_price, coitem_price_uom_id, coitem_price_invuomratio,
             coitem_order_type, coitem_order_id,
             coitem_custpn, coitem_memo,
             coitem_prcost)
      VALUES (_coitemid, pSoheadid,
             pLinenumber, _subnumber,
             _item.itemsite_id, 'O',
             pScheddate, pPromdate,
             _item.qty, _item.bomitem_uom_id, _item.invuomratio,
             0, 0,
             stdCost(_item.item_id), 0,
             0, _item.item_price_uom_id, 1,
             _type, -1,
             '', pMemo,
             0);

      IF (_item.itemsite_createsopr) THEN
        SELECT createPR(cohead_number::INTEGER, 'S', _coitemid) INTO _orderid
        FROM cohead
        WHERE (cohead_id=pSoheadid);
        IF (_orderid > 0) THEN
          UPDATE coitem SET coitem_order_id=_orderid
          WHERE (coitem_id=_coitemid);
        ELSE
          RAISE EXCEPTION 'Could not explode kit. CreatePR failed, result=%', _orderid; 
        END IF;
      END IF;

      IF (_item.itemsite_createsopo) THEN
        SELECT itemsrc_id INTO _itemsrcid
        FROM itemsrc
        WHERE ((itemsrc_item_id=_item.item_id)
        AND (itemsrc_default));

        GET DIAGNOSTICS _count = ROW_COUNT;
        IF (_count > 0) THEN
          PERFORM createPurchaseToSale(_coitemid, _itemsrcid, _item.itemsite_dropship);
        ELSE
          RAISE WARNING 'One or more Kit items are flagged as purchase-to-order for this site, but no default item source is defined.';
        END IF;
      END IF;
     
    END IF;
  END LOOP;

  RETURN _subnumber;
END;

Function: public.explodephantomorder(integer, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPlanordid ALIAS FOR $1;
  pPhantomid ALIAS FOR $2;
  pQty       ALIAS FOR $3;
  _b RECORD;

BEGIN
  FOR _b IN SELECT planord_number, c.itemsite_id AS componentsiteid,
                   calculatenextworkingdate(c.itemsite_warehous_id, planord_startdate, (c.itemsite_leadtime * -1)) AS startdate,
                   planord_startdate AS duedate,
                   bomitem_createwo, c.itemsite_planning_type AS planningtype,
                   (itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL, (bomitem_qtyfxd + pQty * bomitem_qtyper) * (1 + bomitem_scrap))) AS qtyreq,
                   item_type
              FROM bomitem, planord, itemsite AS p, itemsite AS c, item
             WHERE ((bomitem_parent_item_id=p.itemsite_item_id)
               AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id))
               AND (bomitem_item_id=c.itemsite_item_id)
               AND (p.itemsite_warehous_id=c.itemsite_warehous_id)
               AND (c.itemsite_item_id=item_id)
               AND (woEffectiveDate(planord_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
               AND (p.itemsite_id=pPhantomid)
               AND (planord_id=pPlanordid)) LOOP

    IF (_b.item_type = 'F') THEN
      PERFORM explodePhantomOrder(pPlanordid, _b.componentsiteid, _b.qtyreq);
    ELSE
--  Create the Planned Requirement
      INSERT INTO planreq
      ( planreq_source, planreq_source_id,
        planreq_itemsite_id, planreq_qty )
      VALUES
      ( 'P', pPlanordid,
        _b.componentsiteid, _b.qtyreq );

      IF (_b.bomitem_createwo AND _b.planningtype != 'N') THEN
        PERFORM createPlannedOrder( pPlanordid, _b.planord_number, _b.componentsiteid,
                                    _b.qtyreq, _b.startdate, _b.duedate,
                                    FALSE, FALSE, NULL, NULL);
      END IF;
    END IF;

  END LOOP;

  RETURN pPlanordid;
END;

Function: public.explodewo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pExplodeChildren ALIAS FOR $2;
  resultCode INTEGER;
  newWo RECORD;
  _newwoid INTEGER;
  _p RECORD;
  _r RECORD;
  _bbom BOOLEAN;

BEGIN
-- Find out if Breeder BOMs are enabled
  SELECT metric_value='t' INTO _bbom
         FROM metric
         WHERE (metric_name='BBOM');

--  Make sure that this W/O is Open
  SELECT wo_id INTO resultCode
  FROM wo
  WHERE ((wo_status='O')
   AND (wo_id=pWoid));
  IF (NOT FOUND) THEN
    RETURN -4;
  END IF;

--  Make sure that all Component Item Sites exist and are valid
--  Item Sites must be active and not Job Costed
  SELECT bomitem_id INTO resultCode
  FROM wo, bomitem, itemsite
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=bomitem_parent_item_id)
   AND (woEffectiveDate(wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
   AND (wo_id=pWoid)
   AND (bomitem_rev_id=wo_bom_rev_id)
   AND (bomitem_item_id NOT IN
        ( SELECT component.itemsite_item_id
          FROM itemsite AS component, itemsite AS parent
          WHERE ( (wo_itemsite_id=parent.itemsite_id)
           AND (parent.itemsite_item_id=bomitem_parent_item_id)
           AND (bomitem_item_id=component.itemsite_item_id)
           AND (woEffectiveDate(wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
           AND (component.itemsite_active)
           AND (component.itemsite_costmethod <> 'J')
           AND (component.itemsite_warehous_id=parent.itemsite_warehous_id) ) ) ) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

--  If the Parent Item is a Breeder, make sure that all the
--  Co-Product/By-Product Item Sites exist
  IF (_bbom) THEN

    IF ( ( SELECT (item_type='B')
           FROM wo, itemsite, item
           WHERE ( (wo_itemsite_id=itemsite_id)
            AND (itemsite_item_id=item_id)
            AND (wo_id=pWoid) ) ) ) THEN
      SELECT bbomitem_id INTO resultCode
      FROM wo, xtmfg.bbomitem, itemsite
      WHERE ( (wo_itemsite_id=itemsite_id)
       AND (itemsite_item_id=bbomitem_parent_item_id)
       AND (woEffectiveDate(wo_startdate) BETWEEN bbomitem_effective AND (bbomitem_expires - 1))
       AND (wo_id=pWoid)
       AND (bbomitem_item_id NOT IN
            ( SELECT component.itemsite_item_id
              FROM itemsite AS component, itemsite AS parent
              WHERE ( (wo_itemsite_id=parent.itemsite_id)
               AND (parent.itemsite_item_id=bbomitem_parent_item_id)
               AND (bbomitem_item_id=component.itemsite_item_id)
               AND (woEffectiveDate(wo_startdate) BETWEEN bbomitem_effective AND (bbomitem_expires - 1))
               AND (component.itemsite_active)
               AND (component.itemsite_warehous_id=parent.itemsite_warehous_id) ) ) ) )
      LIMIT 1;
      IF (FOUND) THEN
        RETURN -3;
      END IF;
    END IF;
  END IF;

--  Create the W/O Material Requirements
  INSERT INTO womatl
  ( womatl_wo_id, womatl_bomitem_id, womatl_wooper_id, womatl_schedatwooper,
    womatl_itemsite_id,
    womatl_duedate,
    womatl_uom_id, womatl_qtyfxd, womatl_qtyper, womatl_scrap,
    womatl_qtyreq,
    womatl_qtyiss, womatl_qtywipscrap,
    womatl_lastissue, womatl_lastreturn, womatl_cost,
    womatl_picklist, womatl_createwo, womatl_issuewo,
    womatl_issuemethod, womatl_notes, womatl_ref )
  SELECT wo_id, bomitem_id, bomitem_booitem_seq_id, bomitem_schedatwooper,
         cs.itemsite_id,
         CASE WHEN bomitem_schedatwooper THEN COALESCE(calcWooperStartStub(wo_id,bomitem_booitem_seq_id), wo_startdate)
              ELSE wo_startdate
         END,
         bomitem_uom_id, bomitem_qtyfxd, bomitem_qtyper, bomitem_scrap,
         roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id), (bomitem_qtyfxd + bomitem_qtyper * wo_qtyord) * (1 + bomitem_scrap)),
         0, 0,
         startOfTime(), startOfTime(), 0,
         item_picklist, ( (item_type='M') AND (bomitem_createwo) ),
         CASE WHEN ( (item_type='M') AND (bomitem_issuewo) ) THEN TRUE
              WHEN (cs.itemsite_costmethod='J') THEN TRUE
              ELSE FALSE
         END,
         bomitem_issuemethod, bomitem_notes, bomitem_ref 
  FROM bomitem, wo, itemsite AS ps, itemsite AS cs, item
  WHERE ( (wo_itemsite_id=ps.itemsite_id)
   AND (bomitem_parent_item_id=ps.itemsite_item_id)
   AND (bomitem_item_id=cs.itemsite_item_id)
   AND (bomitem_rev_id=wo_bom_rev_id)
   AND (ps.itemsite_warehous_id=cs.itemsite_warehous_id)
   AND (cs.itemsite_item_id=item_id)
   AND (woEffectiveDate(wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
   AND (wo_id=pWoid)
       AND ((bomitem_char_id IS NULL)
       OR  EXISTS (
         SELECT charass_id
         FROM coitem,charass
         WHERE ((charass_target_type='SI')
          AND  (charass_target_id=coitem_id)
          AND  (charass_char_id=bomitem_char_id)
          AND  (charass_value=bomitem_value)
          AND  (wo_ordtype='S')
          AND  (coitem_id=wo_ordid)))) );

--  Update any created P/R's the have the project id as the parent WO.
  UPDATE pr SET pr_prj_id=wo_prj_id
    FROM womatl, wo
   WHERE ((wo_id=pWoid)
     AND  (womatl_wo_id=wo_id)
     AND  (pr_order_type='W')
     AND  (pr_order_id=womatl_id));

--  If the parent Item is a Breeder, create the brddist
--  records for the Co-Products and By-Products
  IF (_bbom) THEN

    INSERT INTO xtmfg.brddist
    ( brddist_wo_id, brddist_wo_qty, brddist_itemsite_id,
      brddist_stdqtyper, brddist_qty, brddist_posted )
    SELECT wo_id, 0, cs.itemsite_id,
           bbomitem_qtyper, 0, FALSE
    FROM wo, xtmfg.bbomitem,
         itemsite AS ps, itemsite AS cs, item
    WHERE ( (bbomitem_parent_item_id=ps.itemsite_item_id)
     AND (wo_itemsite_id=ps.itemsite_id)
     AND (ps.itemsite_item_id=item_id)
     AND (item_type='B')
     AND (bbomitem_item_id=cs.itemsite_item_id)
     AND (cs.itemsite_warehous_id=ps.itemsite_warehous_id)
     AND (wo_id=pWoid) );

  END IF;

--  Insert the W/O Operations if routings enabled
  IF ( ( SELECT (metric_value='t')
         FROM metric
         WHERE (metric_name='Routings') ) ) THEN

    INSERT INTO xtmfg.wooper
    ( wooper_wo_id, wooper_booitem_id, wooper_seqnumber,
      wooper_wrkcnt_id, wooper_stdopn_id,
      wooper_descrip1, wooper_descrip2, wooper_toolref,
      wooper_sutime, wooper_sucosttype, wooper_surpt,
      wooper_rntime, wooper_rncosttype, wooper_rnrpt,
      wooper_rnqtyper,
      wooper_produom, wooper_invproduomratio,
      wooper_issuecomp, wooper_rcvinv,
      wooper_suconsumed, wooper_sucomplete,
      wooper_rnconsumed, wooper_rncomplete,
      wooper_qtyrcv, wooper_instruc, wooper_scheduled,
      wooper_wip_location_id )
    SELECT wo_id, booitem_id, booitem_seqnumber,
           booitem_wrkcnt_id, booitem_stdopn_id,
           booitem_descrip1, booitem_descrip2, booitem_toolref,
           CASE WHEN (booitem_surpt) THEN booitem_sutime
                ELSE 0
           END, booitem_sucosttype, booitem_surpt,
           CASE WHEN ((booitem_rnqtyper = 0) OR (booitem_invproduomratio = 0)) THEN 0
                WHEN (NOT booitem_rnrpt) THEN 0
                ELSE ( ( booitem_rntime /
                         booitem_rnqtyper /
                         booitem_invproduomratio ) * wo_qtyord )
           END, booitem_rncosttype, booitem_rnrpt,
           CASE WHEN (booitem_rnqtyper = 0) THEN 0
                WHEN (NOT booitem_rnrpt) THEN 0
                ELSE (booitem_rntime / booitem_rnqtyper)
           END,
           booitem_produom, booitem_invproduomratio,
           booitem_issuecomp, booitem_rcvinv,
           0::NUMERIC, FALSE,
           0::NUMERIC, FALSE,
           0::NUMERIC, booitem_instruc,
           calculatenextworkingdate(itemsite_warehous_id,wo_startdate,booitem_execday-1),
           booitem_wip_location_id
    FROM xtmfg.booitem, wo, itemsite
    WHERE ((wo_itemsite_id=itemsite_id)
     AND (itemsite_item_id=booitem_item_id)
     AND (booitem_rev_id=wo_boo_rev_id)
     AND (woEffectiveDate(wo_startdate) BETWEEN booitem_effective AND (booitem_expires - 1))
     AND (wo_id=pWoid));

--  Update womatls item to link to wooper items when the respective
--  bomitem record indicates a booitem issue link.
    UPDATE womatl
    SET womatl_wooper_id=wooper_id
    FROM wo,xtmfg.wooper,xtmfg.booitem
    WHERE ((womatl_wooper_id=booitem_seq_id)
     AND (wooper_booitem_id=booitem_id)
     AND (womatl_wo_id=wo_id)
     AND (wooper_wo_id=wo_id)
     AND (wo_boo_rev_id=booitem_rev_id)
     AND (wo_id=pWoid));
    END IF;

-- Handle all of the Phantom material requirements
  WHILE ( ( SELECT COUNT(*)
            FROM womatl, itemsite, item
            WHERE ( (womatl_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (womatl_wo_id=pWoid)
             AND (item_type='F') ) ) > 0 ) LOOP

    FOR _p IN SELECT wo_qtyord, wo_startdate, womatl_id, womatl_wooper_id
              FROM wo, womatl, itemsite, item
              WHERE ( (womatl_itemsite_id=itemsite_id)
               AND (itemsite_item_id=item_id)
               AND (item_type='F')
               AND (womatl_wo_id=wo_id)
               AND (wo_id=pWoid) ) LOOP

      INSERT INTO womatl
      ( womatl_wo_id, womatl_itemsite_id, womatl_wooper_id,
        womatl_schedatwooper, womatl_duedate,
        womatl_uom_id, womatl_qtyfxd, womatl_qtyper, womatl_scrap,
        womatl_qtyreq,
        womatl_qtyiss, womatl_qtywipscrap,
        womatl_lastissue, womatl_lastreturn,
        womatl_cost, womatl_picklist,
        womatl_createwo, womatl_issuewo,
        womatl_issuemethod, womatl_notes, womatl_ref )
      SELECT pWoid, cs.itemsite_id, _p.womatl_wooper_id,
             womatl_schedatwooper, womatl_duedate,
             bomitem_uom_id, bomitem_qtyfxd, (bomitem_qtyper * womatl_qtyper), bomitem_scrap,
             roundQty(itemuomfractionalbyuom(bomitem_item_id, bomitem_uom_id), 
                     (bomitem_qtyfxd + _p.wo_qtyord * bomitem_qtyper * womatl_qtyper) * (1 + bomitem_scrap)),
             0, 0,
             startOfTime(), startOfTime(),
             0, ci.item_picklist,
             ( (ci.item_type='M') AND (bomitem_createwo) ), ( (ci.item_type='M') AND (bomitem_issuewo) ),
             bomitem_issuemethod, bomitem_notes, bomitem_ref
      FROM womatl JOIN wo ON (wo_id=womatl_wo_id)
                  JOIN itemsite ps ON (ps.itemsite_id=womatl_itemsite_id)
                  JOIN item pi ON (pi.item_id=ps.itemsite_item_id)
                  JOIN bomitem ON ( (bomitem_parent_item_id=pi.item_id) AND
                                    (woEffectiveDate(_p.wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1)) AND
                                    (bomitem_rev_id=getActiveRevId('BOM', pi.item_id)) )
                  JOIN item ci ON (ci.item_id=bomitem.bomitem_item_id)
                  JOIN itemsite cs ON ( (cs.itemsite_item_id=ci.item_id) AND
                                        (cs.itemsite_warehous_id=ps.itemsite_warehous_id) )
      WHERE (womatl_id=_p.womatl_id);

      DELETE FROM womatl
      WHERE (womatl_id=_p.womatl_id);

    END LOOP;
  END LOOP;

--  Create W/Os for manufactured component items
  FOR newWo IN SELECT wo_number, nextWoSubnumber(wo_number) AS nextSubnumber,
                      itemsite_id, itemsite_leadtime, womatl_duedate,
                      womatl_wo_id, womatl_qtyreq, womatl_uom_id, wo_prj_id,
                      item_id, item_inv_uom_id, womatl_id
               FROM womatl, wo, itemsite, item
               WHERE ( (womatl_wo_id=wo_id)
                AND (womatl_itemsite_id=itemsite_id)
                AND (womatl_createwo)
                AND (itemsite_wosupply)
                AND (itemsite_item_id=item_id)
                AND (wo_id=pWoid) )
               ORDER BY womatl_id LOOP

    SELECT createWo( newWo.wo_number, newWo.itemsite_id, 1, 
                     itemuomtouom(newWo.item_id,newWo.womatl_uom_id,newWo.item_inv_uom_id,newWo.womatl_qtyreq),
                      newWo.itemsite_leadtime, newWo.womatl_duedate, '',
                      'W', newWo.womatl_wo_id, newWo.wo_prj_id ) INTO _newwoid;

    UPDATE wo SET wo_womatl_id = newWo.womatl_id WHERE wo_id=_newwoid;

  END LOOP;

  UPDATE wo
  SET wo_status='E', wo_adhoc=FALSE
  WHERE (wo_id=pWoid);

  IF (pExplodeChildren) THEN
    SELECT MAX(explodeWo(wo_id, TRUE)) INTO resultCode
    FROM wo
    WHERE ( (wo_ordtype='W')
     AND (wo_ordid=pWoid) );
  END IF;

  RETURN pWoid;
END;

Function: public.explodewoeffective()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _value TEXT;

BEGIN

  SELECT metric_value INTO _value
  FROM metric
  WHERE (metric_name='ExplodeWOEffective');

  RETURN _value;

END;

Function: public.fetchapmemonumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('APMemoNumber')::INTEGER;

Function: public.fetcharmemonumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('ARMemoNumber');

Function: public.fetchcashrcptnumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('CashRcptNumber');

Function: public.fetchcmnumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('CmNumber');

Function: public.fetchcrmaccountnumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('CRMAccountNumber')::INTEGER;

Function: public.fetchdefaultfob(pwarehousid integer)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT warehous_fob
    FROM whsinfo
   WHERE (warehous_id=$1);

Function: public.fetchdefaultshipvia()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal TEXT;
BEGIN
  SELECT shipvia_code INTO _returnVal
  FROM shipvia
  WHERE shipvia_id=
	(SELECT CAST(metric_value AS integer)
	FROM metric
	WHERE metric_name = 'DefaultShipViaId');
  RETURN _returnVal;
END;

Function: public.fetchglsequence()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _sequence INTEGER;

BEGIN

    SELECT NEXTVAL('gltrans_sequence_seq') INTO _sequence;
    RETURN _sequence;

END;

Function: public.fetchincidentnumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('IncidentNumber')::integer;

Function: public.fetchinvcnumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('InvcNumber')::integer;

Function: public.fetchitemuomconvtypes(integer)

Returns: text[]

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemUomConvId ALIAS FOR $1;
  _p RECORD;
  _result text[];
  _cnt INTEGER;

BEGIN

  _cnt := 0;

  FOR _p IN SELECT
    uomtype_name
  FROM itemuomconv, itemuom, uomtype
  WHERE ((itemuomconv_id=pItemUomConvId)
  AND (itemuomconv_id=itemuom_itemuomconv_id)
  AND (itemuom_uomtype_id=uomtype_id))
  LOOP
    _result[_cnt] := _p.uomtype_name; 
    _cnt := _cnt + 1;
  END LOOP;

  RETURN _result;
END;

Function: public.fetchjournalnumber(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUse ALIAS FOR $1;
  _number INTEGER;

BEGIN

  SELECT nextval('journal_number_seq') INTO _number;

  INSERT INTO jrnluse
  (jrnluse_date, jrnluse_number, jrnluse_use)
  VALUES
  (CURRENT_TIMESTAMP, _number, pUse);

  RETURN _number;
  
END;

Function: public.fetchmetricbool(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pMetricName ALIAS FOR $1;
  _returnVal BOOLEAN;
BEGIN
  SELECT CASE 
    WHEN MIN(metric_value) = 't' THEN
     true
    ELSE
     false
    END INTO _returnVal
    FROM metric
   WHERE metric_name = _pMetricName;
  RETURN _returnVal;
END;

Function: public.fetchmetrictext(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pMetricName ALIAS FOR $1;
  _returnVal TEXT;
BEGIN
  SELECT metric_value::TEXT INTO _returnVal
    FROM metric
   WHERE metric_name = _pMetricName;
  RETURN _returnVal;
END;

Function: public.fetchmetricvalue(text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pMetricName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  SELECT CASE WHEN (isNumeric(metric_value)) THEN metric_value::INTEGER
              ELSE NULL
         END INTO _returnVal
    FROM metric
   WHERE metric_name = _pMetricName;
  RETURN _returnVal;
END;

Function: public.fetchnextchecknumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid ALIAS FOR $1;
  _nextChkNumber INTEGER;

BEGIN

  SELECT bankaccnt_nextchknum INTO _nextChkNumber
  FROM bankaccnt
  WHERE (bankaccnt_id=pBankaccntid);

  UPDATE bankaccnt
  SET bankaccnt_nextchknum = (bankaccnt_nextchknum + 1)
  WHERE (bankaccnt_id=pBankaccntid);

  RETURN _nextChkNumber;

END;

Function: public.fetchnextnumber(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  psequence	ALIAS FOR $1;
  _number	TEXT;
  _numcol	TEXT;
  _select	TEXT;
  _table	TEXT;
  _test		TEXT;
  _nextnum	INTEGER;
  _seqiss       seqiss;
  __seqiss      seqiss[];
  _not_issued       BOOLEAN;

BEGIN
  SELECT CAST(orderseq_number AS text), orderseq_number, orderseq_table, orderseq_numcol, COALESCE(orderseq_seqiss, ARRAY[]::seqiss[])
    INTO _number, _nextnum, _table, _numcol, __seqiss
  FROM orderseq
  WHERE (orderseq_name=psequence);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Invalid orderseq_name %', psequence;
  END IF;
  
  LOOP

    _seqiss := (_nextnum, now());

    SELECT count(*) = 0 INTO _not_issued
    FROM (SELECT UNNEST(__seqiss) AS issued) data
    WHERE (issued).seqiss_number = _nextnum;

    _nextnum := _nextnum + 1;

    -- Test if the number has been issued, but not committed
    IF (_not_issued) THEN

      -- Test if the number has been committed
      _select := 'SELECT ' || quote_ident(_numcol) ||
	         ' FROM '  || quote_ident(_table) ||
	         ' WHERE (' || quote_ident(_numcol) || '=' ||
                 quote_literal(_number) || ');';

      EXECUTE _select INTO _test;

      IF (_test IS NULL OR NOT FOUND) THEN
        EXIT;
      END IF;

    END IF;

    -- Number in use, try again
    _number = _nextnum::text;

  END LOOP;

  UPDATE orderseq SET 
    orderseq_number = _nextnum,
    orderseq_seqiss = orderseq_seqiss || _seqiss
  WHERE (orderseq_name=psequence);

  RETURN _number;

END;

Function: public.fetchponumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('PoNumber');

Function: public.fetchprefwarehousid()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _result INTEGER;
BEGIN
    SELECT CAST(usrpref_value AS INTEGER) INTO _result
    FROM usrpref
    WHERE ((usrpref_username=getEffectiveXtUser())
    AND (usrpref_name='PreferredWarehouse'));

    RETURN _result;
END;

Function: public.fetchprnumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('PrNumber')::INTEGER;

Function: public.fetchqunumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('QuNumber');

Function: public.fetchshipmentnumber()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _number		TEXT;
  _test			INTEGER;

BEGIN
  LOOP

    SELECT CAST(nextval('shipment_number_seq') AS TEXT) INTO _number;
    
    SELECT shiphead_id INTO _test
      FROM shiphead
     WHERE (shiphead_number=_number);
    IF (NOT FOUND) THEN
      EXIT;
    END IF;

  END LOOP;

  RETURN _number;
  
END;

Function: public.fetchsonumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('SoNumber');

Function: public.fetchtonumber()

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('ToNumber');

Function: public.fetchusrprefbool(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pPrefName ALIAS FOR $1;
  _returnVal BOOLEAN;
BEGIN
  SELECT CASE 
    WHEN MIN(usrpref_value) = 't' THEN
     true
    ELSE
     false
    END INTO _returnVal
  FROM usrpref
  WHERE ( (usrpref_username=getEffectiveXtUser())
    AND   (usrpref_name=_pPrefName) );
  RETURN _returnVal;
END;

Function: public.fetchvonumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('VcNumber')::INTEGER;

Function: public.fetchwonumber()

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT fetchNextNumber('WoNumber')::INTEGER;

Function: public.financialreport(integer, integer, boolean, boolean, integer)

Returns: SET OF flstmtitem

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlcolid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pShowNumbers ALIAS FOR $3;
  pIndentName ALIAS FOR $4;
  pPrjid ALIAS FOR $5;
  _row flstmtitem%ROWTYPE;
  _p RECORD;
  _x RECORD;
  _priorMoPeriodId INTEGER;
  _priorQtPeriodId INTEGER;
  _priorYrPeriodId INTEGER;
  _first BOOLEAN;
  _prevlevel INTEGER;
  _subgrp INTEGER;
  _qtrInterval TEXT;
  _yrInterval TEXT;

BEGIN

  _priorMoPeriodId := -1;
  _priorQtPeriodId := -1;
  _priorYrPeriodId := -1;
  _first := TRUE;
  _prevlevel :=0;
  _subgrp := 0;

--Get Layout Data
  SELECT flhead_id,flhead_type,
        flcol_month,flcol_quarter,flcol_year,flcol_priortype,
        flcol_priormonth,flcol_priorquarter,flcol_prioryear,
        flcol_priordiff,flcol_priordiffprcnt,flcol_priorprcnt,
        flcol_budget,flcol_budgetdiff,flcol_budgetdiffprcnt,
        flcol_budgetprcnt INTO _p
  FROM flhead,flcol
  WHERE ((flcol_id=pFlcolid)
  AND (flhead_id=flcol_flhead_id));

  IF (_p.flhead_type='B') THEN
    _qtrInterval := 'M';
    _yrInterval := 'M';
  ELSE
    _qtrInterval := 'Q';
    _yrInterval := 'Y';
  END IF;

--Delete old data from all periods
  DELETE FROM flrpt
  WHERE ((flrpt_username=getEffectiveXtUser())
  AND (flrpt_flhead_id=_p.flhead_id));

--Populate report data...
--...for Month
        IF (_p.flcol_month) THEN

        PERFORM financialreport(_p.flhead_id,pPeriodid,'M',pPrjid);

                IF ((_p.flcol_priortype = 'P') AND (_p.flcol_priormonth)) THEN

                        SELECT COALESCE(pp.period_id,-1) INTO _priorMoPeriodId
                        FROM period cp, period pp
                        WHERE ((cp.period_id=pPeriodId)
                        AND (cp.period_start > pp.period_start))
                        ORDER BY pp.period_start DESC LIMIT 1;

                        IF (_priorMoPeriodId IS NOT NULL) THEN
                                PERFORM financialreport(_p.flhead_id,_priorMoPeriodId,'M',pPrjid);
                        END IF;

                        ELSE IF ((_p.flcol_priortype='Y')AND (_p.flcol_priormonth)) THEN

                                SELECT COALESCE(pp.period_id,-1) INTO _priorMoPeriodId
                                FROM period cp, period pp
                                WHERE ((cp.period_id=pPeriodId)
                                AND (cp.period_id != pp.period_id)
                                AND (cp.period_start > pp.period_start)
                                AND (cp.period_number = pp.period_number))
                                ORDER BY pp.period_start DESC LIMIT 1;

                                IF (_priorMoPeriodId IS NOT NULL) THEN
                                        PERFORM financialreport(_p.flhead_id,_priorMoPeriodId,'M',pPrjid);
                                END IF;

                        END IF;

                END IF;
        END IF;

--...for Quarter
        IF (_p.flcol_quarter) THEN

        PERFORM financialreport(_p.flhead_id,pPeriodid,'Q',pPrjid);

        END IF;

        IF ((_p.flcol_priortype='P') AND (_p.flcol_priorquarter)) THEN

                SELECT COALESCE(pp.period_id,-1) INTO _priorQtPeriodId
                FROM period cp, period pp
                WHERE ((cp.period_id=pPeriodId)
                AND (cp.period_start > pp.period_start)
                AND (pp.period_quarter=
                        CASE WHEN cp.period_quarter > 1 THEN
                                cp.period_quarter - 1
                        ELSE 4 END)
                AND (pp.period_start >= cp.period_start - interval '1 year'))
                ORDER BY pp.period_start DESC LIMIT 1;

                IF (_priorQtPeriodId IS NOT NULL) THEN
                        PERFORM financialreport(_p.flhead_id,_priorQtPeriodId,'Q',pPrjid);
                END IF;

                ELSE IF ((_p.flcol_priortype='Y')AND (_p.flcol_priorquarter)) THEN

                        SELECT pp.period_id INTO _priorQtPeriodId
                        FROM period cp, period pp, yearperiod cy, yearperiod py
                        WHERE ((cp.period_id=pPeriodId)
                        AND (cp.period_yearperiod_id=cy.yearperiod_id)
                        AND (pp.period_yearperiod_id=py.yearperiod_id)
                        AND (cp.period_quarter=pp.period_quarter)
                        AND (cy.yearperiod_start > py.yearperiod_start))
                        ORDER BY py.yearperiod_start DESC, pp.period_start DESC LIMIT 1;

                        IF (_priorQtPeriodId IS NOT NULL) THEN
                                PERFORM financialreport(_p.flhead_id,_priorQtPeriodId,'Q',pPrjid);
                        END IF;

                END IF;
        END IF;

--...for Year
        IF (_p.flcol_year) THEN

                PERFORM financialreport(_p.flhead_id,pPeriodid,'Y',pPrjid);

        END IF;

        IF (_p.flcol_prioryear='D') THEN

                SELECT COALESCE(pp.period_id,-1) INTO _priorYrPeriodId
                FROM period cp, period pp
                WHERE ((cp.period_id = pPeriodId)
                AND (cp.period_number = pp.period_number)
                AND (cp.period_start > pp.period_start))
                ORDER BY pp.period_start DESC LIMIT 1;

                IF (_priorYrPeriodId IS NOT NULL) THEN
                        PERFORM financialreport(_p.flhead_id,_priorYrPeriodId,'Y',pPrjid);
                END IF;

                ELSE IF (_p.flcol_prioryear='F') THEN

                        SELECT pp.period_id INTO _priorYrPeriodId
                        FROM period cp, period pp, yearperiod cy, yearperiod py
                        WHERE ((cp.period_id=pPeriodId)
                        AND (cp.period_yearperiod_id=cy.yearperiod_id)
                        AND (pp.period_yearperiod_id=py.yearperiod_id)
                        AND (cy.yearperiod_start > py.yearperiod_start))
                        ORDER BY pp.period_start DESC LIMIT 1;

                        IF (_priorYrPeriodId IS NOT NULL) THEN
                                PERFORM financialreport(_p.flhead_id,_priorYrPeriodId,'Y',pPrjid);
                        END IF;

                END IF;
        END IF;

--Return the data
  FOR _x IN
        SELECT
        flrpt.flrpt_flhead_id AS flstmtitem_flhead_id,
        flrpt.flrpt_period_id AS flstmtitem_period_id,
        flrpt.flrpt_username AS flstmtitem_username,
        flrpt.flrpt_order AS flstmtitem_order,
        flrpt.flrpt_level AS flstmtitem_level,
        flrpt.flrpt_type AS flstmtitem_type,
        flrpt.flrpt_type_id AS flstmtitem_type_id,
        flrpt.flrpt_parent_id AS flstmtitem_parent_id,
        NULL AS flstmtitem_accnt_id,
        CASE
                WHEN (pIndentName) THEN
                        formatindent(flgrp.flgrp_name,flrpt.flrpt_level)
                ELSE flgrp.flgrp_name
        END AS flstmtitem_name,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C'))) THEN
                        (COALESCE(flrptmo.flrpt_diff,0))
                WHEN (flgrp_summarize AND (flhead_type = 'B')) THEN
                        (COALESCE(flrptmo.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_month,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptmo.flrpt_debits,0))
                ELSE NULL
        END AS flstmtitem_monthdb,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptmo.flrpt_credits,0))
                ELSE NULL
        END AS flstmtitem_monthcr,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (COALESCE(flrptmo.flrpt_diffprcnt,0))
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (COALESCE(flrptmo.flrpt_endingprcnt,0))
                ELSE NULL
        END AS flstmtitem_monthprcnt,
        CASE
                WHEN (flgrp_summarize) THEN
                        (flrptmo.flrpt_budget)
                ELSE NULL
        END AS flstmtitem_monthbudget,
        CASE
                WHEN (flgrp_summarize) THEN
                        (flrptmo.flrpt_budgetprcnt)
                ELSE NULL
        END AS flstmtitem_monthbudgetprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptmo.flrpt_budget),0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE((flrptmo.flrpt_ending-flrptmo.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_monthbudgetdiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_diff-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                WHEN (flgrp_summarize AND (flhead_type='B') AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_ending-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                WHEN (flgrp_summarize AND (flrptmo.flrpt_budget = 0)) THEN
                        NULL
                ELSE NULL
        END AS flstmtitem_monthbudgetdiffprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptqt.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_qtr,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptqt.flrpt_debits,0))
                ELSE NULL
        END AS flstmtitem_qtrdb,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptqt.flrpt_credits,0))
                ELSE NULL
        END AS flstmtitem_qtrcr,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (flrptqt.flrpt_diffprcnt)
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (flrptqt.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_qtrprcnt,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptqt.flrpt_budget,0))
                ELSE NULL
        END AS flstmtitem_qtrbudget,
        CASE
                WHEN (flgrp_summarize) THEN
                        (flrptqt.flrpt_budgetprcnt)
                ELSE NULL
        END AS flstmtitem_qtrbudgetprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptqt.flrpt_budget),0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE((flrptqt.flrpt_ending-flrptqt.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_qtrbudgetdiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_diff-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                WHEN (flgrp_summarize AND (flhead_type='B') AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_ending-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_qtrbudgetdiffprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptyr.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptyr.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_year,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptyr.flrpt_debits,0))
                ELSE NULL
        END AS flstmtitem_yeardb,
        CASE
                WHEN (flgrp_summarize) THEN
                        (COALESCE(flrptyr.flrpt_credits,0))
                ELSE NULL
        END AS flstmtitem_yearcr,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (COALESCE(flrptyr.flrpt_diffprcnt,0))
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (COALESCE(flrptyr.flrpt_endingprcnt,0))
                ELSE NULL
        END AS flstmtitem_yearprcnt,
        CASE
                WHEN (flgrp_summarize) THEN
                        (flrptyr.flrpt_budget)
                ELSE NULL
        END AS  flstmtitem_yearbudget,
        CASE
                WHEN (flgrp_summarize) THEN
                        (flrptyr.flrpt_budgetprcnt)
                ELSE NULL
        END AS flstmtitem_yearbudgetprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptyr.flrpt_budget),0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE((flrptyr.flrpt_ending-flrptyr.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_yearbudgetdiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_diff-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                WHEN (flgrp_summarize AND (flhead_type = 'B') AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_ending-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                WHEN (flgrp_summarize AND (flrptyr.flrpt_budget = 0)) THEN
                        NULL
                ELSE NULL
        END AS flstmtitem_yearbudgetdiffprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprmo.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptprmo.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prmonth,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (flrptprmo.flrpt_diffprcnt)
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (flrptprmo.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_prmonthprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptmo.flrpt_diff-flrptprmo.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptmo.flrpt_ending-flrptprmo.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prmonthdiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptprmo.flrpt_diff > 0)) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptprmo.flrpt_diff)/flrptprmo.flrpt_diff,0))
                WHEN (flgrp_summarize AND (flhead_type = 'B') AND (flrptprmo.flrpt_ending > 0)) THEN
                        (COALESCE((flrptmo.flrpt_ending-flrptprmo.flrpt_ending)/flrptprmo.flrpt_ending,0))
                WHEN (flgrp_summarize AND (flrptprmo.flrpt_ending = 0)) THEN
                        NULL
                ELSE NULL
        END AS flstmtitem_prmonthdiffprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprqt.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptprqt.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prqtr,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (flrptprqt.flrpt_diffprcnt)
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (flrptprqt.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_prqtrprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff-flrptprqt.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptqt.flrpt_ending-flrptprqt.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prqtrdiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptprqt.flrpt_diff > 0)) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptprqt.flrpt_diff)/flrptprqt.flrpt_diff,0))
                WHEN (flgrp_summarize AND (flhead_type = 'B') AND (flrptprqt.flrpt_ending > 0)) THEN
                        (COALESCE((flrptqt.flrpt_ending-flrptprqt.flrpt_ending)/flrptprqt.flrpt_ending,0))
                WHEN (flgrp_summarize AND (flrptprqt.flrpt_ending = 0)) THEN
                        NULL
                ELSE NULL
        END AS flstmtitem_prqtrdiffprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptpryr.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptpryr.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_pryear,
        CASE
                WHEN (flgrp_summarize AND flgrp_showdiffprcnt) THEN
                        (flrptpryr.flrpt_diffprcnt)
                WHEN (flgrp_summarize AND flgrp_showendprcnt) THEN
                        (flrptpryr.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_pryearprcnt,
        CASE
                WHEN (flgrp_summarize AND flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptyr.flrpt_diff-flrptpryr.flrpt_diff,0))
                WHEN (flgrp_summarize AND flhead_type = 'B') THEN
                        (COALESCE(flrptyr.flrpt_ending-flrptpryr.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_pryeardiff,
        CASE
                WHEN (flgrp_summarize AND (flhead_type IN ('I','C')) AND (flrptpryr.flrpt_diff > 0)) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptpryr.flrpt_diff)/flrptpryr.flrpt_diff,0))
                WHEN (flgrp_summarize AND (flhead_type = 'B' ) AND (flrptpryr.flrpt_ending > 0)) THEN
                        (COALESCE((flrptyr.flrpt_ending-flrptpryr.flrpt_ending)/flrptpryr.flrpt_ending,0))
                WHEN (flgrp_summarize AND (flrptpryr.flrpt_ending = 0)) THEN
                        NULL
                ELSE NULL
        END AS flstmtitem_pryeardiffprcnt
        FROM flgrp,flhead,
                (SELECT DISTINCT
                        flrpt_flhead_id,
                        flrpt_period_id,
                        flrpt_username,
                        flrpt_order,
                        flrpt_level,
                        flrpt_type,
                        flrpt_type_id,
                        flrpt_parent_id
                FROM flrpt
                WHERE ((flrpt_type='G')
                AND (flrpt_flhead_id=_p.flhead_id)
                AND (flrpt_period_id=pPeriodId)
                AND (flrpt_username=getEffectiveXtUser()))) AS flrpt
                        LEFT OUTER JOIN flrpt flrptmo
                                ON ((flrptmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptmo.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptmo.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptmo.flrpt_interval='M')
                                AND (flrptmo.flrpt_username=flrpt.flrpt_username)
                                AND (flrptmo.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptqt
                                ON ((flrptqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptqt.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptqt.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptqt.flrpt_interval=_qtrInterval)
                                AND (flrptqt.flrpt_username=flrpt.flrpt_username)
                                AND (flrptqt.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptyr
                                ON ((flrptyr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptyr.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptyr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptyr.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptyr.flrpt_interval=_yrInterval)
                                AND (flrptyr.flrpt_username=flrpt.flrpt_username)
                                AND (flrptyr.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptprmo
                                ON ((flrptprmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprmo.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptprmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprmo.flrpt_period_id=_priorMoPeriodId)
                                AND (flrptprmo.flrpt_interval='M')
                                AND (flrptprmo.flrpt_username=flrpt.flrpt_username)
                                AND (flrptprmo.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptprqt
                                ON ((flrptprqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprqt.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptprqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprqt.flrpt_period_id=_priorQtPeriodId)
                                AND (flrptprqt.flrpt_interval='Q')
                                AND (flrptprqt.flrpt_username=flrpt.flrpt_username)
                                AND (flrptprqt.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptpryr
                                ON ((flrptpryr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptpryr.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptpryr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptpryr.flrpt_period_id=_priorYrPeriodId)
                                AND (flrptpryr.flrpt_interval='Y')
                                AND (flrptpryr.flrpt_username=flrpt.flrpt_username)
                                AND (flrptpryr.flrpt_order=flrpt.flrpt_order))
        WHERE ((flgrp_id = flrpt.flrpt_type_id)
        AND (flhead_id = flgrp_flhead_id))
        UNION
        SELECT
        flrpt.flrpt_flhead_id AS flstmtitem_flhead_id,
        flrpt.flrpt_period_id AS flstmtitem_period_id,
        flrpt.flrpt_username AS flstmtitem_username,
        flrpt.flrpt_order AS flstmtitem_order,
        flrpt.flrpt_level AS flstmtitem_level,
        flrpt.flrpt_type AS flstmtitem_type,
        flrpt.flrpt_type_id AS flstmtitem_type_id,
        flrpt.flrpt_parent_id AS flstmtitem_parent_id,
        flrpt.flrpt_accnt_id AS flstmtitem_accnt_id,
        CASE
                WHEN (pIndentName) THEN
                        formatindent(flrpt.flrpt_name,flrpt.flrpt_level)
                ELSE flrpt.flrpt_name
        END AS flstmtitem_name,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptmo.flrpt_diff,0))
                ELSE (COALESCE(flrptmo.flrpt_ending,0))
        END AS flstmtitem_month,
        (COALESCE(flrptmo.flrpt_debits,0)) AS flstmtitem_monthdb,
        (COALESCE(flrptmo.flrpt_credits,0)) AS flstmtitem_monthcr,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (flrptmo.flrpt_diffprcnt)
                WHEN (flitem_showendprcnt) THEN
                        (flrptmo.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_monthprcnt,
        (COALESCE(flrptmo.flrpt_budget,0)) AS flstmtitem_monthbudget,
        (flrptmo.flrpt_budgetprcnt) AS flstmtitem_monthbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptmo.flrpt_budget),0))
                ELSE (COALESCE((flrptmo.flrpt_ending-flrptmo.flrpt_budget),0))
        END AS flstmtitem_monthbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_diff-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                WHEN ((flhead_type='B') AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_ending-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_monthbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff,0))
                ELSE (COALESCE(flrptqt.flrpt_ending,0))
        END AS flstmtitem_qtr,
        (COALESCE(flrptqt.flrpt_debits,0)) AS flstmtitem_qtrdb,
        (COALESCE(flrptqt.flrpt_credits,0)) AS flstmtitem_qtrcr,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (COALESCE(flrptqt.flrpt_diffprcnt,0))
                WHEN (flitem_showendprcnt) THEN
                        (COALESCE(flrptqt.flrpt_endingprcnt,0))
                ELSE NULL
        END AS flstmtitem_qtrprcnt,
        (COALESCE(flrptqt.flrpt_budget,0)) AS flstmtitem_qtrbudget,
        (flrptqt.flrpt_budgetprcnt) AS flstmtitem_qtrbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptqt.flrpt_budget),0))
                ELSE (COALESCE((flrptqt.flrpt_ending-flrptqt.flrpt_budget),0))
        END AS flstmtitem_qtrbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_diff-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                WHEN ((flhead_type='B') AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_ending-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_qtrbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptyr.flrpt_diff,0))
                ELSE (COALESCE(flrptyr.flrpt_ending,0))
        END AS flstmtitem_year,
        (COALESCE(flrptyr.flrpt_debits,0)) AS flstmtitem_yeardb,
        (COALESCE(flrptyr.flrpt_credits,0)) AS flstmtitem_yearcr,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (flrptyr.flrpt_diffprcnt)
                WHEN (flitem_showendprcnt) THEN
                        (flrptyr.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_yearprcnt,
        (COALESCE(flrptyr.flrpt_budget,0)) AS  flstmtitem_yearbudget,
        (flrptyr.flrpt_budgetprcnt) AS flstmtitem_yearbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptyr.flrpt_budget),0))
                ELSE (COALESCE((flrptyr.flrpt_ending-flrptyr.flrpt_budget),0))
        END AS flstmtitem_yearbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_diff-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                WHEN ((flhead_type = 'B') AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_ending-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_yearbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprmo.flrpt_diff,0))
                ELSE (COALESCE(flrptprmo.flrpt_ending,0))
        END AS flstmtitem_prmonth,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (flrptprmo.flrpt_diffprcnt)
                WHEN (flitem_showendprcnt) THEN
                        (flrptprmo.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_prmonthprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptmo.flrpt_diff-flrptprmo.flrpt_diff,0))
                ELSE (COALESCE(flrptmo.flrpt_ending-flrptprmo.flrpt_ending,0))
        END AS flstmtitem_prmonthdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptprmo.flrpt_diff > 0)) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptprmo.flrpt_diff)/flrptprmo.flrpt_diff,0))
                WHEN ((flhead_type = 'B') AND (flrptprmo.flrpt_ending > 0)) THEN
                        (COALESCE((flrptmo.flrpt_ending-flrptprmo.flrpt_ending)/flrptprmo.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prmonthdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprqt.flrpt_diff,0))
                ELSE (COALESCE(flrptprqt.flrpt_ending,0))
        END AS flstmtitem_prqtr,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (flrptprqt.flrpt_diffprcnt)
                WHEN (flitem_showendprcnt) THEN
                        (flrptprqt.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_prqtrprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff-flrptprqt.flrpt_diff,0))
                ELSE (COALESCE(flrptqt.flrpt_ending-flrptprqt.flrpt_ending,0))
        END AS flstmtitem_prqtrdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptprqt.flrpt_diff > 0)) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptprqt.flrpt_diff)/flrptprqt.flrpt_diff,0))
                WHEN ((flhead_type = 'B') AND (flrptprqt.flrpt_ending > 0)) THEN
                        (COALESCE((flrptqt.flrpt_ending-flrptprqt.flrpt_ending)/flrptprqt.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prqtrdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptpryr.flrpt_diff,0))
                ELSE (COALESCE(flrptpryr.flrpt_ending,0))
        END AS flstmtitem_pryear,
        CASE
                WHEN (flitem_showdiffprcnt) THEN
                        (flrptpryr.flrpt_diffprcnt)
                WHEN (flitem_showendprcnt) THEN
                        (flrptpryr.flrpt_endingprcnt)
                ELSE NULL
        END AS flstmtitem_pryearprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptpryr.flrpt_diff),0))
                ELSE (COALESCE((flrptyr.flrpt_ending-flrptpryr.flrpt_ending),0))
        END AS flstmtitem_pryeardiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptpryr.flrpt_diff > 0)) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptpryr.flrpt_diff)/flrptpryr.flrpt_diff,0))
                WHEN ((flhead_type = 'B' ) AND (flrptpryr.flrpt_ending > 0)) THEN
                        (COALESCE((flrptyr.flrpt_ending-flrptpryr.flrpt_ending)/flrptpryr.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_pryeardiffprcnt
        FROM flitem,flhead,
                (SELECT DISTINCT
                        flrpt_flhead_id,
                        flrpt_period_id,
                        flrpt_username,
                        flrpt_order,
                        flrpt_level,
                        flrpt_type,
                        flrpt_type_id,
                        flrpt_parent_id,
                        accnt_id AS flrpt_accnt_id,
                        CASE WHEN (pShowNumbers) THEN
                                (formatGLAccount(accnt_id) || '-' || accnt_descrip)
                        ELSE accnt_descrip END AS flrpt_name
                FROM flrpt,accnt
                WHERE ((flrpt_type='I')
                AND (flrpt_flhead_id=_p.flhead_id)
                AND (flrpt_period_id=pPeriodid)
                AND (flrpt_username=getEffectiveXtUser())
                AND (accnt_id=flrpt_accnt_id))) AS flrpt
                        LEFT OUTER JOIN flrpt flrptmo
                                ON ((flrptmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptmo.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptmo.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptmo.flrpt_interval='M')
                                AND (flrptmo.flrpt_username=flrpt.flrpt_username)
                                AND (flrptmo.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptqt
                                ON ((flrptqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptqt.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptqt.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptqt.flrpt_interval=_qtrInterval)
                                AND (flrptqt.flrpt_username=flrpt.flrpt_username)
                                AND (flrptqt.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptyr
                                ON ((flrptyr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptyr.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptyr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptyr.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptyr.flrpt_interval=_yrInterval)
                                AND (flrptyr.flrpt_username=flrpt.flrpt_username)
                                AND (flrptyr.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptprmo
                                ON ((flrptprmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprmo.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptprmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprmo.flrpt_period_id=_priorMoPeriodId)
                                AND (flrptprmo.flrpt_interval='M')
                                AND (flrptprmo.flrpt_username=flrpt.flrpt_username)
                                AND (flrptprmo.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptprqt
                                ON ((flrptprqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprqt.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptprqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprqt.flrpt_period_id=_priorQtPeriodId)
                                AND (flrptprqt.flrpt_interval='Q')
                                AND (flrptprqt.flrpt_username=flrpt.flrpt_username)
                                AND (flrptprqt.flrpt_order=flrpt.flrpt_order))
                        LEFT OUTER JOIN flrpt flrptpryr
                                ON ((flrptpryr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptpryr.flrpt_type_id=flrpt.flrpt_type_id)
                                AND (flrptpryr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptpryr.flrpt_period_id=_priorYrPeriodId)
                                AND (flrptpryr.flrpt_interval='Y')
                                AND (flrptpryr.flrpt_username=flrpt.flrpt_username)
                                AND (flrptpryr.flrpt_order=flrpt.flrpt_order) )
        WHERE ((flitem_id = flrpt.flrpt_type_id)
        AND (flhead_id = flitem_flhead_id))
        UNION
        SELECT
        flrpt.flrpt_flhead_id AS flstmtitem_flhead_id,
        flrpt.flrpt_period_id AS flstmtitem_period_id,
        flrpt.flrpt_username AS flstmtitem_username,
        flrpt.flrpt_order AS flstmtitem_order,
        flrpt.flrpt_level AS flstmtitem_level,
        flrpt.flrpt_type AS flstmtitem_type,
        flrpt.flrpt_type_id AS flstmtitem_type_id,
        flrpt.flrpt_parent_id AS flstmtitem_parent_id,
        NULL AS flstmtitem_accnt_id,
        CASE WHEN(flrpt.flrpt_type='T' AND flrpt.flrpt_level=0) THEN
                        COALESCE(flrpt.flrpt_altname, 'Total')
                WHEN(flrpt.flrpt_type='T') THEN
                        formatindent(COALESCE(flrpt.flrpt_altname, 'Subtotal') ,
                        (CASE WHEN pIndentName THEN flrpt.flrpt_level ELSE 0 END))
                ELSE formatindent(('Type ' || flrpt.flrpt_type || ' ' || text(flrpt.flrpt_type_id)),
                        (CASE WHEN pIndentName THEN flrpt.flrpt_level ELSE 0 END))
                END AS flstmtitem_name,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptmo.flrpt_diff,0))
                ELSE (COALESCE(flrptmo.flrpt_ending,0))
        END AS flstmtitem_month,
        (COALESCE(flrptmo.flrpt_debits,0)) AS flstmtitem_monthdb,
        (COALESCE(flrptmo.flrpt_credits,0)) AS flstmtitem_monthcr,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptmo.flrpt_diffprcnt)
                ELSE (flrptmo.flrpt_endingprcnt)
        END AS flstmtitem_monthprcnt,
        (COALESCE(flrptmo.flrpt_budget,0)) AS flstmtitem_monthbudget,
        (flrptmo.flrpt_budgetprcnt) AS flstmtitem_monthbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptmo.flrpt_budget),0))
                ELSE (COALESCE((flrptmo.flrpt_ending-flrptmo.flrpt_budget),0))
        END AS flstmtitem_monthbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_diff-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                WHEN ((flhead_type='B') AND (flrptmo.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptmo.flrpt_ending-flrptmo.flrpt_budget)/flrptmo.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_monthbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff,0))
                ELSE (COALESCE(flrptqt.flrpt_ending,0))
        END AS flstmtitem_qtr,
        (COALESCE(flrptqt.flrpt_debits,0)) AS flstmtitem_qtrdb,
        (COALESCE(flrptqt.flrpt_credits,0)) AS flstmtitem_qtrcr,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptqt.flrpt_diffprcnt)
                ELSE (flrptqt.flrpt_endingprcnt)
        END AS flstmtitem_qtrprcnt,
        (COALESCE(flrptqt.flrpt_budget,0)) AS flstmtitem_qtrbudget,
        (flrptqt.flrpt_budgetprcnt) AS flstmtitem_qtrbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptqt.flrpt_budget),0))
                ELSE (COALESCE((flrptqt.flrpt_ending-flrptqt.flrpt_budget),0))
        END AS flstmtitem_qtrbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_diff-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                WHEN ((flhead_type='B') AND (flrptqt.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptqt.flrpt_ending-flrptqt.flrpt_budget)/flrptqt.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_qtrbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptyr.flrpt_diff,0))
                ELSE (COALESCE(flrptyr.flrpt_ending,0))
        END AS flstmtitem_year,
        (COALESCE(flrptyr.flrpt_debits,0)) AS flstmtitem_yeardb,
        (COALESCE(flrptyr.flrpt_credits,0)) AS flstmtitem_yearcr,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptyr.flrpt_diffprcnt)
                ELSE (flrptyr.flrpt_endingprcnt)
        END AS flstmtitem_yearprcnt,
        (COALESCE(flrptyr.flrpt_budget,0)) AS  flstmtitem_yearbudget,
        (flrptyr.flrpt_budgetprcnt) AS flstmtitem_yearbudgetprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptyr.flrpt_budget),0))
                ELSE (COALESCE((flrptyr.flrpt_ending-flrptyr.flrpt_budget),0))
        END AS flstmtitem_yearbudgetdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_diff-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                WHEN ((flhead_type = 'B') AND (flrptyr.flrpt_budget > 0)) THEN
                        (COALESCE(((flrptyr.flrpt_ending-flrptyr.flrpt_budget)/flrptyr.flrpt_budget),0))
                ELSE NULL
        END AS flstmtitem_yearbudgetdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprmo.flrpt_diff,0))
                ELSE (COALESCE(flrptprmo.flrpt_ending,0))
        END AS flstmtitem_prmonth,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptprmo.flrpt_diffprcnt)
                ELSE (flrptprmo.flrpt_endingprcnt)
        END AS flstmtitem_prmonthprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptmo.flrpt_diff-flrptprmo.flrpt_diff,0))
                ELSE (COALESCE(flrptmo.flrpt_ending-flrptprmo.flrpt_ending,0))
        END AS flstmtitem_prmonthdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptprmo.flrpt_diff > 0)) THEN
                        (COALESCE((flrptmo.flrpt_diff-flrptprmo.flrpt_diff)/flrptprmo.flrpt_diff,0))
                WHEN ((flhead_type = 'B') AND (flrptprmo.flrpt_ending > 0)) THEN
                        (COALESCE((flrptmo.flrpt_ending-flrptprmo.flrpt_ending)/flrptprmo.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prmonthdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptprqt.flrpt_diff,0))
                ELSE (COALESCE(flrptprqt.flrpt_ending,0))
        END AS flstmtitem_prqtr,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptprqt.flrpt_diffprcnt)
                ELSE (flrptprqt.flrpt_endingprcnt)
        END AS flstmtitem_prqtrprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptqt.flrpt_diff-flrptprqt.flrpt_diff,0))
                ELSE (COALESCE(flrptqt.flrpt_ending-flrptprqt.flrpt_ending,0))
        END AS flstmtitem_prqtrdiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptprqt.flrpt_diff > 0)) THEN
                        (COALESCE((flrptqt.flrpt_diff-flrptprqt.flrpt_diff)/flrptprqt.flrpt_diff,0))
                WHEN ((flhead_type = 'B') AND (flrptprqt.flrpt_ending > 0)) THEN
                        (COALESCE((flrptqt.flrpt_ending-flrptprqt.flrpt_ending)/flrptprqt.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_prqtrdiffprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptpryr.flrpt_diff,0))
                ELSE (COALESCE(flrptpryr.flrpt_ending,0))
        END AS flstmtitem_pryear,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (flrptpryr.flrpt_diffprcnt)
                ELSE (flrptpryr.flrpt_endingprcnt)
        END AS flstmtitem_pryearprcnt,
        CASE
                WHEN (flhead_type IN ('I','C')) THEN
                        (COALESCE(flrptyr.flrpt_diff-flrptpryr.flrpt_diff,0))
                ELSE (COALESCE(flrptyr.flrpt_ending-flrptpryr.flrpt_ending,0))
        END AS flstmtitem_pryeardiff,
        CASE
                WHEN ((flhead_type IN ('I','C')) AND (flrptpryr.flrpt_diff > 0)) THEN
                        (COALESCE((flrptyr.flrpt_diff-flrptpryr.flrpt_diff)/flrptpryr.flrpt_diff,0))
                WHEN ((flhead_type = 'B' ) AND (flrptpryr.flrpt_ending > 0)) THEN
                        (COALESCE((flrptyr.flrpt_ending-flrptpryr.flrpt_ending)/flrptpryr.flrpt_ending,0))
                ELSE NULL
        END AS flstmtitem_pryeardiffprcnt
        FROM flhead CROSS JOIN (SELECT DISTINCT
                        flrpt_flhead_id,
                        flrpt_period_id,
                        flrpt_username,
                        flrpt_order,
                        flrpt_level,
                        flrpt_type,
                        flrpt_type_id,
                        flrpt_parent_id,
                        flrpt_altname
                FROM flrpt
                WHERE ((NOT (flrpt_type IN ('G','I','S')))
                AND (flrpt_flhead_id=_p.flhead_id)
                AND (flrpt_period_id=pPeriodId)
                AND (flrpt_username=getEffectiveXtUser()))) AS flrpt
                        LEFT OUTER JOIN flrpt flrptmo
                                ON ((flrptmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptmo.flrpt_order=flrpt.flrpt_order)
                                AND (flrptmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptmo.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptmo.flrpt_interval='M')
                                AND (flrptmo.flrpt_username=flrpt.flrpt_username))
                        LEFT OUTER JOIN flrpt flrptqt
                                ON ((flrptqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptqt.flrpt_order=flrpt.flrpt_order)
                                AND (flrptqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptqt.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptqt.flrpt_interval=_qtrInterval)
                                AND (flrptqt.flrpt_username=flrpt.flrpt_username))
                        LEFT OUTER JOIN flrpt flrptyr
                                ON ((flrptyr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptyr.flrpt_order=flrpt.flrpt_order)
                                AND (flrptyr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptyr.flrpt_period_id=flrpt.flrpt_period_id)
                                AND (flrptyr.flrpt_interval=_yrInterval)
                                AND (flrptyr.flrpt_username=flrpt.flrpt_username))
                        LEFT OUTER JOIN flrpt flrptprmo
                                ON ((flrptprmo.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprmo.flrpt_order=flrpt.flrpt_order)
                                AND (flrptprmo.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprmo.flrpt_period_id=_priorMoPeriodId)
                                AND (flrptprmo.flrpt_interval='M')
                                AND (flrptprmo.flrpt_username=flrpt.flrpt_username))
                        LEFT OUTER JOIN flrpt flrptprqt
                                ON ((flrptprqt.flrpt_type=flrpt.flrpt_type)
                                AND (flrptprqt.flrpt_order=flrpt.flrpt_order)
                                AND (flrptprqt.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptprqt.flrpt_period_id=_priorQtPeriodId)
                                AND (flrptprqt.flrpt_interval='Q')
                                AND (flrptprqt.flrpt_username=flrpt.flrpt_username))
                        LEFT OUTER JOIN flrpt flrptpryr
                                ON ((flrptpryr.flrpt_type=flrpt.flrpt_type)
                                AND (flrptpryr.flrpt_order=flrpt.flrpt_order)
                                AND (flrptpryr.flrpt_flhead_id=flrpt.flrpt_flhead_id)
                                AND (flrptpryr.flrpt_period_id=_priorYrPeriodId)
                                AND (flrptpryr.flrpt_interval='Y')
                                AND (flrptpryr.flrpt_username=flrpt.flrpt_username))
        WHERE (flhead_id=flrpt.flrpt_flhead_id)
        ORDER BY flstmtitem_order
        LOOP
                IF _prevlevel > _x.flstmtitem_level THEN
                        _subgrp := _subgrp+1;
                END IF;
                _prevlevel:=_x.flstmtitem_level;
                _row.flstmtitem_subgrp := _subgrp;

                IF NOT _first THEN
                        RETURN NEXT _row;
                END IF;

                _first := FALSE;

                _row.flstmtitem_flhead_id := _x.flstmtitem_flhead_id;
                _row.flstmtitem_period_id := _x.flstmtitem_period_id;
                _row.flstmtitem_username := _x.flstmtitem_username;
                _row.flstmtitem_order := _x.flstmtitem_order;
                _row.flstmtitem_level := _x.flstmtitem_level;
                _row.flstmtitem_type := _x.flstmtitem_type;
                _row.flstmtitem_type_id := _x.flstmtitem_type_id;
                _row.flstmtitem_parent_id := _x.flstmtitem_parent_id;
                _row.flstmtitem_accnt_id := _x.flstmtitem_accnt_id;
                _row.flstmtitem_name := _x.flstmtitem_name;
                _row.flstmtitem_month := _x.flstmtitem_month;
                _row.flstmtitem_monthdb := _x.flstmtitem_monthdb;
                _row.flstmtitem_monthcr := _x.flstmtitem_monthcr;
                _row.flstmtitem_monthprcnt := _x.flstmtitem_monthprcnt;
                _row.flstmtitem_monthbudget := _x.flstmtitem_monthbudget;
                _row.flstmtitem_monthbudgetprcnt := _x.flstmtitem_monthbudgetprcnt;
                _row.flstmtitem_monthbudgetdiff := _x.flstmtitem_monthbudgetdiff;
                _row.flstmtitem_monthbudgetdiffprcnt := _x.flstmtitem_monthbudgetdiffprcnt;
                _row.flstmtitem_qtr := _x.flstmtitem_qtr;
                _row.flstmtitem_qtrdb := _x.flstmtitem_qtrdb;
                _row.flstmtitem_qtrcr := _x.flstmtitem_qtrcr;
                _row.flstmtitem_qtrprcnt := _x.flstmtitem_qtrprcnt;
                _row.flstmtitem_qtrbudget := _x.flstmtitem_qtrbudget;
                _row.flstmtitem_qtrbudgetprcnt := _x.flstmtitem_qtrbudgetprcnt;
                _row.flstmtitem_qtrbudgetdiff := _x.flstmtitem_qtrbudgetdiff;
                _row.flstmtitem_qtrbudgetdiffprcnt := _x.flstmtitem_qtrbudgetdiffprcnt;
                _row.flstmtitem_year := _x.flstmtitem_year;
                _row.flstmtitem_yeardb := _x.flstmtitem_yeardb;
                _row.flstmtitem_yearcr := _x.flstmtitem_yearcr;
                _row.flstmtitem_yearprcnt := _x.flstmtitem_yearprcnt;
                _row.flstmtitem_yearbudget := _x.flstmtitem_yearbudget;
                _row.flstmtitem_yearbudgetprcnt := _x.flstmtitem_yearbudgetprcnt;
                _row.flstmtitem_yearbudgetdiff := _x.flstmtitem_yearbudgetdiff;
                _row.flstmtitem_yearbudgetdiffprcnt := _x.flstmtitem_yearbudgetdiffprcnt;
                _row.flstmtitem_prmonth := _x.flstmtitem_prmonth;
                _row.flstmtitem_prmonthprcnt := _x.flstmtitem_prmonthprcnt;
                _row.flstmtitem_prmonthdiff := _x.flstmtitem_prmonthdiff;
                _row.flstmtitem_prmonthdiffprcnt := _x.flstmtitem_prmonthdiffprcnt;
                _row.flstmtitem_prqtr := _x.flstmtitem_prqtr;
                _row.flstmtitem_prqtrprcnt := _x.flstmtitem_prqtrprcnt;
                _row.flstmtitem_prqtrdiff := _x.flstmtitem_prqtrdiff;
                _row.flstmtitem_prqtrdiffprcnt := _x.flstmtitem_prqtrdiffprcnt;
                _row.flstmtitem_pryear := _x.flstmtitem_pryear;
                _row.flstmtitem_pryearprcnt := _x.flstmtitem_pryearprcnt;
                _row.flstmtitem_pryeardiff := _x.flstmtitem_pryeardiff;
                _row.flstmtitem_pryeardiffprcnt := _x.flstmtitem_pryeardiffprcnt;

        END LOOP;

        _row.flstmtitem_subgrp := _subgrp + 1;
        RETURN NEXT _row;
END;

Function: public.financialreport(integer, integer, bpchar, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pInterval ALIAS FOR $3;
  pPrjid    ALIAS FOR $4;

  _r RECORD;
  _t RECORD;
  _s RECORD;

BEGIN

-- Validate Interval
   IF pInterval <> 'M' AND pInterval <> 'Q' AND pInterval <> 'Y' THEN
     RAISE EXCEPTION 'Invalid Interval --> %', pInterval;
   END IF;

-- Get rid of any old reporting done by this user for the specified criteria
  DELETE FROM flrpt
   WHERE ((flrpt_flhead_id=pFlheadid)
     AND  (flrpt_period_id=pPeriodId)
     AND  (flrpt_interval=pInterval)
     AND  (flrpt_username=getEffectiveXtUser()));

-- Find out if we need to show a Grand Total and which if any of the values
-- we want to show in that grand total.
  SELECT flhead_showtotal,
         CASE WHEN(flhead_showstart) THEN 0.00
              ELSE NULL
         END AS beginning,
         CASE WHEN(flhead_showend) THEN 0.00
              ELSE NULL
         END AS ending,
         CASE WHEN(flhead_showdelta) THEN 0.00
              ELSE NULL
         END AS debits,
         CASE WHEN(flhead_showdelta) THEN 0.00
              ELSE NULL
         END AS credits,
         CASE WHEN(flhead_showbudget) THEN 0.00
              ELSE NULL
         END AS budget,
         CASE WHEN(flhead_showdiff) THEN 0.00
              ELSE NULL
         END AS diff,
         CASE WHEN(flhead_showcustom) THEN 0.00
              ELSE NULL
         END AS custom,
         CASE WHEN(flhead_usealttotal) THEN flhead_alttotal
              ELSE NULL
         END AS altname INTO _r
    FROM flhead
   WHERE (flhead_id=pFlheadid);
  IF (NOT FOUND) THEN
    return FALSE;
  END IF;

-- If showing a Grand Total then create a record as a Group which acts
-- as a parent to the whole report. This allows the code to update as
-- it would for normal group total values.
  IF (_r.flhead_showtotal) THEN
    INSERT INTO flrpt
           (flrpt_flhead_id, flrpt_period_id, flrpt_username,
            flrpt_order, flrpt_level, flrpt_type, flrpt_type_id,
            flrpt_beginning, flrpt_ending,
            flrpt_debits, flrpt_credits, flrpt_budget, flrpt_diff,
            flrpt_custom, flrpt_altname, flrpt_interval )
    VALUES (pFlheadid, pPeriodid, getEffectiveXtUser(),
            0, -1, 'G', -1,
            _r.beginning, _r.ending,
            _r.debits, _r.credits, _r.budget, _r.diff,
            _r.custom, _r.altname, pInterval );
  END IF;

  PERFORM insertFlGroup(pFlheadid, pPeriodid, -1, 0, FALSE, pInterval, pPrjid);

-- go through the list of records that need percentages calculated and perform
-- those calculations.
  FOR _t IN SELECT flrpt_order, CASE WHEN(flgrp_prcnt_flgrp_id = -1) THEN flgrp_flgrp_id ELSE flgrp_prcnt_flgrp_id END AS flgrp_id
              FROM flrpt, flgrp
             WHERE ((flrpt_flhead_id=pFlheadid)
               AND  (flrpt_period_id=pPeriodid)
               AND  (flrpt_interval=pInterval)
               AND  (flrpt_username=getEffectiveXtUser())
               AND  (flrpt_type='G')
               AND  (flrpt_type_id=flgrp_id))
             UNION
            SELECT flrpt_order, CASE WHEN(flitem_prcnt_flgrp_id = -1) THEN flitem_flgrp_id ELSE flitem_prcnt_flgrp_id END AS flgrp_id
              FROM flrpt, flitem
             WHERE ((flrpt_flhead_id=pFlheadid)
               AND  (flrpt_period_id=pPeriodid)
               AND  (flrpt_interval=pInterval)
               AND  (flrpt_username=getEffectiveXtUser())
               AND  (flrpt_type='I')
               AND  (flrpt_type_id=flitem_id))
             UNION
            SELECT flrpt_order, CASE WHEN(flspec_prcnt_flgrp_id = -1) THEN flspec_flgrp_id ELSE flspec_prcnt_flgrp_id END AS flgrp_id
              FROM flrpt, flspec
             WHERE ((flrpt_flhead_id=pFlheadid)
               AND  (flrpt_period_id=pPeriodid)
               AND  (flrpt_interval=pInterval)
               AND  (flrpt_username=getEffectiveXtUser())
               AND  (flrpt_type='S')
               AND  (flrpt_type_id=flspec_id)) LOOP

    IF( (_t.flgrp_id=-1) OR (NOT (SELECT flgrp_summarize FROM flgrp WHERE flgrp_id=_t.flgrp_id)) ) THEN
      SELECT COALESCE(SUM(flrpt_beginning),0) AS beginningTotal,
             COALESCE(SUM(flrpt_ending),0) AS endingTotal,
             COALESCE(SUM(flrpt_debits),0) AS debitsTotal,
             COALESCE(SUM(flrpt_credits),0) AS creditsTotal,
             COALESCE(SUM(flrpt_budget),0) AS budgetTotal,
             COALESCE(SUM(flrpt_diff), 0) AS diffTotal,
             COALESCE(SUM(flrpt_custom), 0) AS customTotal INTO _s
        FROM flrpt
       WHERE ((flrpt_flhead_id=pFlheadid)
         AND  (flrpt_period_id=pPeriodid)
         AND  (flrpt_interval=pInterval)
         AND  (flrpt_username=getEffectiveXtUser())
         AND  (flrpt_type != 'T')
         AND  (flrpt_parent_id=_t.flgrp_id));
    ELSE
      SELECT COALESCE(SUM(flrpt_beginning),0) AS beginningTotal,
             COALESCE(SUM(flrpt_ending),0) AS endingTotal,
             COALESCE(SUM(flrpt_debits),0) AS debitsTotal,
             COALESCE(SUM(flrpt_credits),0) AS creditsTotal,
             COALESCE(SUM(flrpt_budget),0) AS budgetTotal,
             COALESCE(SUM(flrpt_diff), 0) AS diffTotal,
             COALESCE(SUM(flrpt_custom), 0) AS customTotal INTO _s
        FROM flrpt
       WHERE ((flrpt_flhead_id=pFlheadid)
         AND  (flrpt_period_id=pPeriodid)
         AND  (flrpt_interval=pInterval)
         AND  (flrpt_username=getEffectiveXtUser())
         AND  (flrpt_type = 'G')
         AND  (flrpt_type_id=_t.flgrp_id));
    END IF;

    UPDATE flrpt SET flrpt_beginningprcnt = flrpt_beginningprcnt + flrpt_beginning / CASE WHEN (_s.beginningTotal=0) THEN 1 ELSE _s.beginningTotal END,
                     flrpt_endingprcnt = flrpt_endingprcnt + flrpt_ending / CASE WHEN (_s.endingTotal=0) THEN 1 ELSE _s.endingTotal END,
                     flrpt_debitsprcnt = flrpt_debitsprcnt + flrpt_debits / CASE WHEN (_s.debitsTotal=0) THEN 1 ELSE _s.debitsTotal END,
                     flrpt_creditsprcnt = flrpt_creditsprcnt + flrpt_credits / CASE WHEN (_s.creditsTotal=0) THEN 1 ELSE _s.creditsTotal END,
                     flrpt_budgetprcnt = flrpt_budgetprcnt + flrpt_budget / CASE WHEN (_s.budgetTotal=0) THEN 1 ELSE _s.budgetTotal END,
                     flrpt_diffprcnt = flrpt_diffprcnt + flrpt_diff / CASE WHEN (_s.diffTotal=0) THEN 1 ELSE _s.diffTotal END,
                     flrpt_customprcnt = flrpt_customprcnt + flrpt_custom / CASE WHEN (_s.customTotal=0) THEN 1 ELSE _s.customTotal END
     WHERE ((flrpt_flhead_id=pFlheadid)
       AND  (flrpt_period_id=pPeriodid)
       AND  (flrpt_interval=pInterval)
       AND  (flrpt_username=getEffectiveXtUser())
       AND  (flrpt_order=_t.flrpt_order));
  END LOOP;


-- Update any subtotal records to reflect the percentage values of the parents
-- since those are calculated after the subtotal records were created.
  FOR _t IN SELECT a.flrpt_order AS flrpt_order,
                   b.flrpt_beginningprcnt AS flrpt_beginningprcnt,
                   b.flrpt_endingprcnt AS flrpt_endingprcnt,
                   b.flrpt_debitsprcnt AS flrpt_debitsprcnt,
                   b.flrpt_creditsprcnt AS flrpt_creditsprcnt,
                   b.flrpt_budgetprcnt AS flrpt_budgetprcnt,
                   b.flrpt_diffprcnt AS flrpt_diffprcnt,
                   b.flrpt_customprcnt AS flrpt_customprcnt
              FROM flrpt AS a, flrpt AS b
             WHERE ((a.flrpt_flhead_id=pFlheadid)
               AND  (a.flrpt_period_id=pPeriodid)
               AND  (a.flrpt_interval=pInterval)
               AND  (a.flrpt_username=getEffectiveXtUser())
               AND  (a.flrpt_type='T')
               AND  (b.flrpt_flhead_id=a.flrpt_flhead_id)
               AND  (b.flrpt_period_id=a.flrpt_period_id)
               AND  (b.flrpt_interval=pInterval)
               AND  (b.flrpt_username=a.flrpt_username)
               AND  (b.flrpt_type='G')
               AND  (b.flrpt_type_id=a.flrpt_parent_id)) LOOP
    UPDATE flrpt SET flrpt_beginningprcnt=flrpt_beginningprcnt + _t.flrpt_beginningprcnt,
                     flrpt_endingprcnt=flrpt_endingprcnt + _t.flrpt_endingprcnt,
                     flrpt_debitsprcnt=flrpt_debitsprcnt + _t.flrpt_debitsprcnt,
                     flrpt_creditsprcnt=flrpt_creditsprcnt + _t.flrpt_creditsprcnt,
                     flrpt_budgetprcnt=flrpt_budgetprcnt + _t.flrpt_budgetprcnt,
                     flrpt_diffprcnt=flrpt_diffprcnt + _t.flrpt_diffprcnt,
                     flrpt_customprcnt=flrpt_customprcnt + _t.flrpt_customprcnt
               WHERE ((flrpt_flhead_id=pFlheadid)
                 AND  (flrpt_period_id=pPeriodid)
                 AND  (flrpt_interval=pInterval)
                 AND  (flrpt_username=getEffectiveXtUser())
                 AND  (flrpt_order=_t.flrpt_order));
  END LOOP;

-- If showing a Grand total then move the record we created early to the
-- end of the report and marked as a Total record.
  IF (_r.flhead_showtotal) THEN
    UPDATE flrpt
       SET flrpt_order = COALESCE((SELECT MAX(flrpt_order)
                                     FROM flrpt
                                    WHERE ((flrpt_flhead_id=pFlheadid)
                                      AND  (flrpt_period_id=pPeriodid)
                                      AND  (flrpt_interval=pInterval)
                                      AND  (flrpt_username=getEffectiveXtUser()))
                                  ), 0) + 1,
           flrpt_level = 0,
           flrpt_type = 'T'
     WHERE ((flrpt_flhead_id=pFlheadid)
       AND  (flrpt_period_id=pPeriodid)
       AND  (flrpt_interval=pInterval)
       AND  (flrpt_username=getEffectiveXtUser())
       AND  (flrpt_order=0)
       AND  (flrpt_level = -1)
       AND  (flrpt_type = 'G')
       AND  (flrpt_type_id=-1));
  END IF;

  return TRUE;
END;

Function: public.financialreport(integer, integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pPrjid    ALIAS FOR $3;
  _result bool;

BEGIN

  SELECT financialreport(pFlheadid,pPeriodid,'M', pPrjid) INTO _result;

  RETURN _result;
END;

Function: public.financialreport(integer, integer[], bpchar, boolean, integer)

Returns: SET OF fltrenditem

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadId ALIAS FOR $1;
  pPeriodIds ALIAS FOR $2;
  pInterval ALIAS FOR $3;
  pShowNumbers ALIAS FOR $4;
  pPrjid ALIAS FOR $5;
  _row fltrenditem%ROWTYPE;
  _type CHAR;
  _p RECORD;
  _count INTEGER;
  _n NUMERIC;
  _fld NUMERIC[];
  _grndttl NUMERIC;
  _i INTEGER;
  _first BOOLEAN;
  _prevlevel INTEGER;
  _subgrp INTEGER;

BEGIN
        _first := true;
        _subgrp := 0;

        IF ARRAY_UPPER(pPeriodIds,1) <= 12 THEN
                _count := ARRAY_UPPER(pPeriodIds,1);
        ELSE
                _count := 12;
        END IF;

        --Get Type
        SELECT flhead_type FROM flhead INTO _type WHERE flhead_id=pFlheadId;

        --Build Financial Data
        FOR _i IN 1.._count
        LOOP
                PERFORM financialreport(pFlheadId,pPeriodIds[_i],pInterval,pPrjid);
        END LOOP;

        --Get Row Data
        FOR _p IN
        SELECT flrpt_flhead_id,
                flrpt_username,
                flrpt_order,
                flrpt_level,
                flrpt_type,
                flrpt_type_id,
                flrpt_parent_id,
                flrpt_accnt_id,
                formatindent(flgrp.flgrp_name,flrpt.flrpt_level) AS flrpt_name,
                CASE
                        WHEN (flgrp_summarize AND (_type IN ('I','C'))) THEN
                                (COALESCE(flrpt_diff,0))
                        WHEN (flgrp_summarize AND (_type = 'B')) THEN
                                (COALESCE(flrpt_ending,0))
                        ELSE NULL
                END AS f_fld1,
                flgrp_summarize AS display
        FROM flrpt,flgrp
        WHERE ((flrpt_flhead_id=pFlheadId)
        AND (flgrp_id=flrpt_type_id)
        AND (flrpt_type='G')
        AND (flrpt_period_id=pPeriodIds[1])
        AND (flrpt_interval=pInterval)
        AND (flrpt_username=getEffectiveXtUser()))
        UNION
        SELECT flrpt_flhead_id,
                flrpt_username,
                flrpt_order,
                flrpt_level,
                flrpt_type,
                flrpt_type_id,
                flrpt_parent_id,
                flrpt_accnt_id,
                formatindent(accnt_descrip,flrpt.flrpt_level) AS flrpt_name,
                CASE
                        WHEN (_type IN ('I','C')) THEN
                                (COALESCE(flrpt_diff,0))
                        WHEN (_type = 'B') THEN
                                (COALESCE(flrpt_ending,0))
                        ELSE NULL
                END AS f_fld1,
                true AS display
        FROM flrpt,flitem,accnt
        WHERE ((flrpt_flhead_id=pFlheadId)
        AND (flrpt_accnt_id=accnt_id)
        AND (flitem_id=flrpt_type_id)
        AND (flrpt_type='I')
        AND (flrpt_period_id=pPeriodIds[1])
        AND (flrpt_interval=pInterval)
        AND (flrpt_username=getEffectiveXtUser()))
        UNION
        SELECT flrpt_flhead_id,
                flrpt_username,
                flrpt_order,
                flrpt_level,
                flrpt_type,
                flrpt_type_id,
                flrpt_parent_id,
                flrpt_accnt_id,
                CASE
                        WHEN (flrpt.flrpt_type='T' AND flrpt.flrpt_level=0) THEN
                                COALESCE(flrpt.flrpt_altname, 'Total')
                        WHEN (flrpt.flrpt_type='T') THEN
                                formatindent(COALESCE(flrpt.flrpt_altname, 'Subtotal') ,flrpt.flrpt_level) 

                        ELSE
                                formatindent(('Type ' || flrpt.flrpt_type || ' ' || text(flrpt.flrpt_type_id)), flrpt.flrpt_level)
                END AS flstmtitem_name,
                CASE
                        WHEN (_type IN ('I','C')) THEN
                                (COALESCE(flrpt_diff,0))
                        WHEN (_type = 'B') THEN
                                (COALESCE(flrpt_ending,0))
                        ELSE NULL
                END AS f_fld1,
                true AS display
        FROM flrpt
        WHERE ((flrpt_flhead_id=pFlheadId)
        AND (flrpt_type NOT IN ('I','S','G'))
        AND (flrpt_period_id=pPeriodIds[1])
        AND (flrpt_interval=pInterval)
        AND (flrpt_username=getEffectiveXtUser()))
        ORDER BY flrpt_order
        LOOP

                IF _type IN ('I','C') THEN
                        _grndttl := _p.f_fld1;
                END IF;

                --Loop through and calculate period column values
                IF (_p.display) THEN
                        FOR _i IN 2.._count
                        LOOP
                                SELECT
                                CASE
                                        WHEN (_type IN ('I','C')) THEN
                                                COALESCE(flrpt_diff,0)
                                        WHEN (_type = 'B') THEN
                                                COALESCE(flrpt_ending,0)
                                        ELSE NULL
                                END INTO _n
                                FROM flrpt
                                WHERE ((flrpt_flhead_id=pFlheadId)
                                AND (flrpt_period_id=pPeriodIds[_i])
                                AND (flrpt_interval=pInterval)
                                AND (flrpt_username=getEffectiveXtUser())
                                AND (flrpt_order=_p.flrpt_order));
                                _fld[_i-1] := _n;
                                IF _type IN ('I','C') THEN
                                        _grndttl := _grndttl+_n;
                                END IF;
                        END LOOP;
                END IF;

                --Send it all back to the caller
                IF _prevlevel > _p.flrpt_level THEN
                        _subgrp := _subgrp+1;
                END IF;
                _prevlevel:=_p.flrpt_level;
                _row.fltrenditem_subgrp := _subgrp;

                IF NOT _first THEN
                        RETURN NEXT _row;
                END IF;

                _first := FALSE;

                _row.fltrenditem_flhead_id := _p.flrpt_flhead_id;
                _row.fltrenditem_username := _p.flrpt_username;
                _row.fltrenditem_order := _p.flrpt_order;
                _row.fltrenditem_level := _p.flrpt_level;
                _row.fltrenditem_type := _p.flrpt_type;
                _row.fltrenditem_type_id := _p.flrpt_type_id;
                _row.fltrenditem_parent_id := _p.flrpt_parent_id;
                _row.fltrenditem_accnt_id := _p.flrpt_accnt_id;
                _row.fltrenditem_name := _p.flrpt_name;
                IF (_p.display) THEN
                        _row.fltrenditem_fld1 := (_p.f_fld1);
                        _row.fltrenditem_fld2 := (_fld[1]);
                        _row.fltrenditem_fld3 := (_fld[2]);
                        _row.fltrenditem_fld4 := (_fld[3]);
                        _row.fltrenditem_fld5 := (_fld[4]);
                        _row.fltrenditem_fld6 := (_fld[5]);
                        _row.fltrenditem_fld7 := (_fld[6]);
                        _row.fltrenditem_fld8 := (_fld[7]);
                        _row.fltrenditem_fld9 := (_fld[8]);
                        _row.fltrenditem_fld10 := (_fld[9]);
                        _row.fltrenditem_fld11 := (_fld[10]);
                        _row.fltrenditem_fld12 := (_fld[11]);
                        _row.fltrenditem_grndttl := (_grndttl);
                ELSE
                        _row.fltrenditem_fld1 := NULL;
                        _row.fltrenditem_fld2 := NULL;
                        _row.fltrenditem_fld3 := NULL;
                        _row.fltrenditem_fld4 := NULL;
                        _row.fltrenditem_fld5 := NULL;
                        _row.fltrenditem_fld6 := NULL;
                        _row.fltrenditem_fld7 := NULL;
                        _row.fltrenditem_fld8 := NULL;
                        _row.fltrenditem_fld9 := NULL;
                        _row.fltrenditem_fld10 := NULL;
                        _row.fltrenditem_fld11 := NULL;
                        _row.fltrenditem_fld12 := NULL;
                        _row.fltrenditem_grndttl := NULL;
                END IF;

        END LOOP;

        _row.fltrenditem_subgrp := _subgrp + 1;
        RETURN NEXT _row;

END;

Function: public.findapaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceAPToGL')) THEN
    RETURN 0;
  END IF;

  SELECT apaccnt_ap_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendinfo ON (apaccnt_vendtype_id=vend_vendtype_id)
  WHERE (vend_id=pVendid);
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  SELECT apaccnt_ap_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendtype ON (vendtype_code ~ apaccnt_vendtype)
    JOIN vendinfo ON (vend_vendtype_id=vendtype_id)
  WHERE ((apaccnt_vendtype_id=-1)
     AND (vend_id=pVendid));
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findapdiscountaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceAPToGL')) THEN
    RETURN 0;
  END IF;

  SELECT apaccnt_discount_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendinfo ON (apaccnt_vendtype_id=vend_vendtype_id)
  WHERE (vend_id=pVendid);
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  SELECT apaccnt_discount_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendtype ON (vendtype_code ~ apaccnt_vendtype)
    JOIN vendinfo ON (vend_vendtype_id=vendtype_id)
  WHERE ((apaccnt_vendtype_id=-1)
     AND (vend_id=pVendid));
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findapprepaidaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceAPToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Vendor Type specific Account
  SELECT apaccnt_prepaid_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendinfo ON (apaccnt_vendtype_id=vend_vendtype_id)
  WHERE (vend_id=pVendid);
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Vendor Type pattern
  SELECT apaccnt_prepaid_accnt_id INTO _accntid
    FROM apaccnt
    JOIN vendtype ON (vendtype_code ~ apaccnt_vendtype)
    JOIN vendinfo ON (vend_vendtype_id=vendtype_id)
  WHERE ((apaccnt_vendtype_id=-1)
     AND (vend_id=pVendid));
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findaraccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceARToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Customer Type specific Account
  SELECT araccnt_ar_accnt_id INTO _accntid
  FROM araccnt, custinfo
  WHERE ( (araccnt_custtype_id=cust_custtype_id)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Customer Type pattern
  SELECT araccnt_ar_accnt_id INTO _accntid
  FROM araccnt, custinfo, custtype
  WHERE ( (custtype_code ~ araccnt_custtype)
   AND (araccnt_custtype_id=-1)
   AND (cust_custtype_id=custtype_id)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findardiscountaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceARToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Customer Type specific Account
  SELECT araccnt_discount_accnt_id INTO _accntid
  FROM araccnt, custinfo
  WHERE ( (araccnt_custtype_id=cust_custtype_id)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Customer Type pattern
  SELECT araccnt_discount_accnt_id INTO _accntid
  FROM araccnt, custinfo, custtype
  WHERE ( (custtype_code ~ araccnt_custtype)
   AND (cust_custtype_id=custtype_id)
   AND (araccnt_custtype_id=-1)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findcalendarorigin(integer)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCalheadid ALIAS FOR $1;
  _originType CHAR(1);
  _origin DATE;

BEGIN

  SELECT calhead_origin INTO _originType
  FROM calhead
  WHERE (calhead_id=pCalheadid);

  IF (NOT FOUND) THEN
    _origin := NULL;

  ELSIF (_originType = 'D') THEN
    _origin := CURRENT_DATE;

  ELSIF (_originType = 'E') THEN
    _origin := (CURRENT_DATE + 1);

  ELSIF (_originType = 'W') THEN
    _origin := (CURRENT_DATE - EXTRACT(DOW FROM CURRENT_DATE)::INTEGER);

  ELSIF (_originType = 'X') THEN
    _origin := ((CURRENT_DATE - EXTRACT(DOW FROM CURRENT_DATE)::INTEGER) + INTERVAL '1 week');

  ELSIF (_originType = 'M') THEN
    _origin := date_trunc('month', CURRENT_DATE);

  ELSIF (_originType = 'N') THEN
    _origin := (date_trunc('month', CURRENT_DATE) + INTERVAL '1 month');

  ELSIF (_originType = 'L') THEN
    _origin := (date_trunc('year', CURRENT_DATE) - INTERVAL '1 year');

  ELSIF (_originType = 'Y') THEN
    _origin := date_trunc('year', CURRENT_DATE);

  ELSIF (_originType = 'Z') THEN
    _origin := (date_trunc('year', CURRENT_DATE) + INTERVAL '1 year');

  ELSE
    _origin := NULL;
  END IF;

  RETURN _origin;

  END;

Function: public.findcustomerform(integer, bpchar)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pFormtype ALIAS FOR $2;
  _f RECORD;
  _found BOOLEAN;

BEGIN

--  Check for a Customer Type specific Form
  SELECT custform.* INTO _f
    FROM custform
    JOIN custinfo ON (custform_custtype_id=cust_custtype_id)
  WHERE (cust_id=pCustid);

  IF (FOUND) THEN
    _found := TRUE;
  ELSE
--  Check for a Customer Type pattern
    SELECT custform.* INTO _f
      FROM custform
      JOIN custtype ON (custtype_code ~ custform_custtype)
      JOIN custinfo ON (cust_custtype_id=custtype_id)
    WHERE ((custform_custtype_id=-1)
       AND (cust_id=pCustid));

    IF (FOUND) THEN
      _found := TRUE;
    ELSE
      _found := FALSE;
    END IF;
  END IF;

  IF (_found) THEN
    IF ( (pFormType = 'I') AND (_f.custform_invoice_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_invoice_report_name;

    ELSIF ( (pFormType = 'C') AND (_f.custform_creditmemo_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_creditmemo_report_name;

    ELSIF ( (pFormType = 'S') AND (_f.custform_statement_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_statement_report_name;

    ELSIF ( (pFormType = 'Q') AND (_f.custform_quote_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_quote_report_name;

    ELSIF ( (pFormType = 'P') AND (_f.custform_packinglist_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_packinglist_report_name;

    ELSIF ( (pFormType = 'L') AND (_f.custform_sopicklist_report_name IS NOT NULL) ) THEN
      RETURN _f.custform_sopicklist_report_name;
    END IF;

  END IF;

  IF (pFormType = 'I') THEN
    RETURN 'Invoice';
  ELSIF (pFormType = 'C') THEN
    RETURN 'CreditMemo';
  ELSIF (pFormType = 'S') THEN
    RETURN 'Statement';
  ELSIF (pFormType = 'Q') THEN
    RETURN 'Quote';
  ELSIF (pFormType = 'P') THEN
    RETURN 'PackingList-Shipment';
  ELSIF (pFormType = 'L') THEN
    RETURN 'PackingList';
  END IF;

END;

Function: public.finddeferredaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceARToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Customer Type specific Account
  SELECT araccnt_deferred_accnt_id INTO _accntid
    FROM araccnt
    JOIN custinfo ON (araccnt_custtype_id=cust_custtype_id)
  WHERE (cust_id=pCustid);
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Customer Type pattern
  SELECT araccnt_deferred_accnt_id INTO _accntid
    FROM araccnt
    JOIN custtype ON (custtype_code ~ araccnt_custtype)
    JOIN custinfo ON (cust_custtype_id=custtype_id)
  WHERE ((araccnt_custtype_id=-1)
     AND (cust_id=pCustid));
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findfreightaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceARToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Customer Type specific Account
  SELECT araccnt_freight_accnt_id INTO _accntid
  FROM araccnt, custinfo
  WHERE ( (araccnt_custtype_id=cust_custtype_id)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Customer Type pattern
  SELECT araccnt_freight_accnt_id INTO _accntid
  FROM araccnt, custinfo, custtype
  WHERE ( (custtype_code ~ araccnt_custtype)
   AND (cust_custtype_id=custtype_id)
   AND (araccnt_custtype_id=-1)
   AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Find the default
  SELECT metric_value::INTEGER INTO _accntid
  FROM metric
  WHERE (metric_name='FreightAccount');
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findperiodend(integer)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCalitemid ALIAS FOR $1;
  _calType CHAR(1);
  _calItem RECORD;
  _start DATE;
  _loop INTEGER;

BEGIN

  SELECT calhead_type INTO _calType
  FROM calhead, acalitem
  WHERE ((acalitem_calhead_id=calhead_id)
   AND (acalitem_id=pCalitemid));

  IF (NOT FOUND) THEN
    SELECT calhead_type INTO _calType
    FROM calhead, rcalitem
    WHERE ((rcalitem_calhead_id=calhead_id)
     AND (rcalitem_id=pCalitemid));

    IF (NOT FOUND) THEN
      RETURN NULL;
    END IF;
  END IF;

  IF (_calType = 'A') THEN
    RETURN ( SELECT (findPeriodStart(acalitem_id) + acalitem_periodlength - 1)
             FROM acalitem
             WHERE (acalitem_id=pCalitemid) );

  ELSIF (_calType = 'R') THEN

--  Grab the relative calitem's particulars
    SELECT rcalitem_periodtype, rcalitem_periodcount INTO _calitem
    FROM rcalitem
    WHERE (rcalitem_id=pCalitemid);

    IF (NOT FOUND) THEN
      RETURN NULL;
    END If;

--  Grab the origin of the calitem
    SELECT findPeriodStart(pCalitemid) INTO _start;

    IF (_start IS NULL) THEN

--  If days...
    ELSIF (_calitem.rcalitem_periodtype = 'D') THEN
      _start := (_start + _calitem.rcalitem_periodcount - 1);

--  If weeks... (gotta be a better way)
    ELSIF (_calitem.rcalitem_periodtype = 'W') THEN
      _loop := _calitem.rcalitem_periodcount;

      WHILE (_loop > 0) LOOP
        _start := (_start + INTERVAL '1 week');
        _loop := (_loop - 1);
      END LOOP;

      _start := (_start - 1);

--  If months... (gotta be a better way)
    ELSIF (_calitem.rcalitem_periodtype = 'M') THEN
      _loop := _calitem.rcalitem_periodcount;

      WHILE (_loop > 0) LOOP
        _start := (_start + INTERVAL '1 month');
        _loop := (_loop - 1);
      END LOOP;

      _start := (_start - 1);

--  If years... (gotta be a better way)
    ELSIF (_calitem.rcalitem_periodtype = 'Y') THEN
      _loop := _calitem.rcalitem_periodcount;

      WHILE (_loop > 0) LOOP
        _start := (_start + INTERVAL '1 year');
        _loop := (_loop - 1);
      END LOOP;

      _start := (_start - 1);

    ELSE
      _start := NULL;
    END IF;

  ELSE
    _start := NULL;
  END IF;

  RETURN _start;

END;

Function: public.findperiodstart(integer)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCalitemid ALIAS FOR $1;
  _calType CHAR(1);
  _calItem RECORD;
  _start DATE;
  _loop INTEGER;

BEGIN

  SELECT calhead_type INTO _calType
  FROM calhead, acalitem
  WHERE ((acalitem_calhead_id=calhead_id)
   AND (acalitem_id=pCalitemid));

  IF (NOT FOUND) THEN
    SELECT calhead_type INTO _calType
    FROM calhead, rcalitem
    WHERE ((rcalitem_calhead_id=calhead_id)
     AND (rcalitem_id=pCalitemid));

    IF (NOT FOUND) THEN
      RETURN NULL;
    END IF;
  END IF;

  IF (_calType = 'A') THEN
    RETURN ( SELECT acalitem_periodstart
             FROM acalitem
             WHERE (acalitem_id=pCalitemid) );

  ELSIF (_calType = 'R') THEN

--  Grab the relative calitem's particulars
    SELECT rcalitem_offsettype, rcalitem_offsetcount INTO _calitem
    FROM rcalitem
    WHERE (rcalitem_id=pCalitemid);

    IF (NOT FOUND) THEN
      RETURN NULL;
    END If;

--  Grab the origin of the calitem's parend calhead
    SELECT findCalendarOrigin(calhead_id) INTO _start
    FROM calhead, rcalitem
    WHERE ((rcalitem_calhead_id=calhead_id)
     AND (rcalitem_id=pCalitemid));

--  If days...
    IF (_calitem.rcalitem_offsettype = 'D') THEN
      _start := (_start + _calitem.rcalitem_offsetcount);

--  If weeks...
    ELSIF (_calitem.rcalitem_offsettype = 'W') THEN
      _start := (_start + (_calitem.rcalitem_offsetcount * 7));

--  If months... (gotta be a better way)
    ELSIF (_calitem.rcalitem_offsettype = 'M') THEN
      _loop := _calitem.rcalitem_offsetcount;

      IF (_loop > 0) THEN
        WHILE (_loop > 0) LOOP
          _start := (_start + INTERVAL '1 month');
          _loop := _loop - 1;
        END LOOP;
      ELSE
        WHILE (_loop < 0) LOOP
          _start := (_start - INTERVAL '1 month');
          _loop := _loop + 1;
        END LOOP;
      END IF;

--  If years... (gotta be a better way)
    ELSIF (_calitem.rcalitem_offsettype = 'Y') THEN
      _loop := _calitem.rcalitem_offsetcount;

      IF (_loop > 0) THEN
        WHILE (_loop > 0) LOOP
          _start := (_start + INTERVAL '1 year');
          _loop := _loop - 1;
        END LOOP;
      ELSE
        WHILE (_loop < 0) LOOP
          _start := (_start - INTERVAL '1 year');
          _loop := _loop + 1;
        END LOOP;
      END IF;

    ELSE
      _start := NULL;
    END IF;

  ELSE
    _start := NULL;
  END IF;

  RETURN _start;

END;

Function: public.findprepaidaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  _accntid INTEGER;

BEGIN

  IF (NOT fetchMetricBool('InterfaceARToGL')) THEN
    RETURN 0;
  END IF;

--  Check for a Customer Type specific Account
  SELECT araccnt_prepaid_accnt_id INTO _accntid
    FROM araccnt
    JOIN custinfo ON (araccnt_custtype_id=cust_custtype_id)
  WHERE (cust_id=pCustid);
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

--  Check for a Customer Type pattern
  SELECT araccnt_prepaid_accnt_id INTO _accntid
    FROM araccnt
    JOIN custtype ON (custtype_code ~ araccnt_custtype)
    JOIN custinfo ON (cust_custtype_id=custtype_id)
  WHERE ((araccnt_custtype_id=-1)
     AND (cust_id=pCustid) );
  IF (FOUND) THEN
    RETURN _accntid;
  END IF;

  RETURN -1;

END;

Function: public.findsalesaccnt(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN findSalesAccnt($1, 'IS', $2, NULL, NULL);
END;

Function: public.findsalesaccnt(integer, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN findSalesAccnt($1, $2, $3, NULL, NULL);
END;

Function: public.findsalesaccnt(pshipzoneid integer, psaletypeid text, pcustid integer, pidtype integer, pid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _s RECORD;

BEGIN

  IF (pidType = 'I') THEN
    --  Check for a custtype specific rule
    SELECT salesaccnt_id,
           CASE WHEN (salesaccnt_custtype_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_prodcat_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_saletype_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_shipzone_id<>-1) THEN 1 ELSE 0 END AS orderby
    INTO _s
    FROM salesaccnt, item, prodcat, custinfo, custtype
    WHERE ( (salesaccnt_warehous_id=-1)
      AND  (item_prodcat_id=prodcat_id)
      AND  (cust_custtype_id=custtype_id)
      AND  ( (salesaccnt_prodcat='.*') OR
	    ( (salesaccnt_prodcat_id=-1) AND
	      (salesaccnt_prodcat<>'') AND
	      (prodcat_code ~ salesaccnt_prodcat) ) OR
	    ( (salesaccnt_prodcat_id=prodcat_id) ) )
      AND  ( (salesaccnt_custtype='.*') OR
	    ( (salesaccnt_custtype_id=-1) AND
	      (salesaccnt_custtype<>'') AND
	      (custtype_code ~ salesaccnt_custtype) ) OR
	    ( (salesaccnt_custtype_id=custtype_id) ) )
      AND  ( (salesaccnt_shipzone_id=-1) OR
	     (salesaccnt_shipzone_id=pShipzoneid) )
      AND  ( (salesaccnt_saletype_id=-1) OR
	     (salesaccnt_saletype_id=pSaletypeid) )
      AND (item_id=pid)
      AND (cust_id=pCustid) )
    ORDER BY orderby, salesaccnt_custtype DESC, salesaccnt_prodcat DESC,
             salesaccnt_saletype_id DESC, salesaccnt_shipzone_id DESC
     LIMIT 1;

  ELSIF (pidType = 'IS') THEN
    --  Check for a custtype specific rule
    SELECT salesaccnt_id,
           CASE WHEN (salesaccnt_warehous_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_custtype_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_prodcat_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_saletype_id<>-1) THEN 1 ELSE 0 END +
           CASE WHEN (salesaccnt_shipzone_id<>-1) THEN 1 ELSE 0 END AS orderby
    INTO _s
    FROM salesaccnt, itemsite, item, prodcat, custinfo, custtype
    WHERE ( ( (salesaccnt_warehous_id=-1) OR
	      (salesaccnt_warehous_id=itemsite_warehous_id) )
     AND (itemsite_item_id=item_id)
     AND (item_prodcat_id=prodcat_id)
     AND (cust_custtype_id=custtype_id)
     AND ( (salesaccnt_prodcat='.*') OR
	   ( (salesaccnt_prodcat_id=-1) AND
	     (salesaccnt_prodcat<>'') AND
	     (prodcat_code ~ salesaccnt_prodcat) ) OR
	   ( (salesaccnt_prodcat_id=prodcat_id) ) )
     AND ( (salesaccnt_custtype='.*') OR
	   ( (salesaccnt_custtype_id=-1) AND
	     (salesaccnt_custtype<>'') AND
	     (custtype_code ~ salesaccnt_custtype) ) OR
	   ( (salesaccnt_custtype_id=custtype_id) ) )
     AND  ( (salesaccnt_shipzone_id=-1) OR
            (salesaccnt_shipzone_id=pShipzoneid) )
     AND  ( (salesaccnt_saletype_id=-1) OR
            (salesaccnt_saletype_id=pSaletypeid) )
     AND (itemsite_id=pid)
     AND (cust_id=pCustid) ) 
    ORDER BY orderby DESC, salesaccnt_custtype DESC, salesaccnt_prodcat DESC, salesaccnt_warehous_id DESC,
             salesaccnt_saletype_id DESC, salesaccnt_shipzone_id DESC
    LIMIT 1;

  ELSE
    RETURN -2;	-- invalid pidType
  END IF;

  IF (FOUND) THEN
    RETURN _s.salesaccnt_id;
  END IF;

  RETURN -1;

END;

Function: public.findspecialfinancial(text, text, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUnit ALIAS FOR $1;
  pType ALIAS FOR $2;
  pPeriodid ALIAS FOR $3;

  _value NUMERIC;
BEGIN

  _value := 0.00;

  IF ('OpenAR' = pType) THEN
    IF ( pUnit IN ('D','E') ) THEN
      SELECT SUM( CASE WHEN (aropen_doctype IN ('C', 'R')) THEN ((aropen_amount - aropen_paid) * -1)
                       ELSE (aropen_amount - aropen_paid) END ) INTO _value
        FROM aropen, period
       WHERE ((aropen_open)
         AND  (aropen_duedate BETWEEN period_start AND period_end)
         AND  (period_id=pPeriodid));

      IF ('E' = pUnit) THEN
        _value := 0.00 - _value;
      END IF;
    END IF;
  END IF;

  IF ('OpenAP' = pType) THEN
    IF ( pUnit IN ('C','E') ) THEN
      SELECT SUM( CASE WHEN (apopen_doctype='C') THEN ((apopen_amount - apopen_paid) * -1)
                       ELSE (apopen_amount - apopen_paid) END ) INTO _value
        FROM apopen, period
       WHERE ((apopen_open)
         AND  (apopen_duedate BETWEEN period_start AND period_end)
         AND  (period_id=pPeriodid));
    END IF;
  END IF;

  RETURN _value;

END;

Function: public.first(anyelement)

Returns: anyelement

Language: INTERNAL

aggregate_dummy

Function: public.first_agg(anyelement, anyelement)

Returns: anyelement

Language: SQL

  SELECT CASE WHEN $1 IS NULL THEN $2 ELSE $1 END;

Function: public.firstline(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource ALIAS FOR $1;
  _result TEXT := '';

BEGIN
  SELECT regexp_replace(pSource, E'^(\r?\n)*([^\r\n]*)\r?\n.*', E'\\2') INTO _result;
  RETURN _result;
END;

Function: public.fixacl()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r        RECORD;
  _count    INTEGER := 0;
  _oldgrp   BOOLEAN := false;
  _objtype  TEXT;
  _table    TEXT;
  _schema   TEXT;

BEGIN
  IF EXISTS(SELECT 1 FROM pg_group WHERE groname = 'openmfg') THEN
    _oldgrp := true;
  END IF;
  
  FOR _r IN SELECT relname, nspname, relkind,
                   CASE relkind WHEN 'r' THEN 1
                                WHEN 'v' THEN 2
                                WHEN 'S' THEN 3
                                ELSE 4
                   END AS seq
            FROM pg_catalog.pg_class c, pg_namespace n
            WHERE ((n.oid=c.relnamespace)
              AND  (nspname in ('public', 'api') OR
                    nspname in (SELECT pkghead_name FROM pkghead))
              AND  (relkind in ('S', 'r', 'v')))
            ORDER BY seq
  LOOP
    _schema := quote_ident(_r.nspname);
    _table  := quote_ident(_r.relname);

    RAISE DEBUG '%.%', _schema, _table;
    
    IF (_oldgrp) THEN
      EXECUTE 'REVOKE ALL ON ' || _schema || '.' || _table || ' FROM openmfg;';
    END IF;
    EXECUTE 'REVOKE ALL ON ' || _schema || '.' || _table || ' FROM PUBLIC;';
    EXECUTE 'GRANT ALL ON '  || _schema || '.' || _table || ' TO GROUP xtrole;';
    _count := _count + 1;

    _objtype := CASE _r.relkind WHEN 'S' THEN 'SEQUENCE'
                                WHEN 'r' THEN 'TABLE'
                                WHEN 'v' THEN 'VIEW'
                                ELSE NULL
                END;
    IF (_objtype IS NOT NULL) THEN
      BEGIN
        EXECUTE 'ALTER ' || _objtype || ' ' ||
                _schema || '.' || _table || ' OWNER TO admin;';
      EXCEPTION WHEN OTHERS THEN
        RAISE WARNING 'Could not change ownership of %.% to admin',
                      _schema, _table;
      END;
    END IF;

  END LOOP;

  RETURN _count;
END;

Function: public.formatabachecks(integer, integer, text)

Returns: SET OF achline

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pbankaccntid     ALIAS FOR $1;   -- all unprinted checks for this bankaccnt
  pcheckheadid     ALIAS FOR $2;   -- but if 2nd arg not null then just 1 check
  penckey          ALIAS FOR $3;
  _bank            RECORD;
  _batchcount      INTEGER := 0;
  _batchdate       DATE;
  _check           RECORD;
  _vendnumber      TEXT;
  _vendname        TEXT;
  _filenum         TEXT;
  _prevsec         TEXT;
  _row             achline%ROWTYPE;
  _totalcr         NUMERIC := 0;
  _totaldb         NUMERIC := 0;
  _detailcount     INTEGER := 0;     -- count of type 1 entries
  _vendbsb         TEXT;

BEGIN
  -- General notes:
  -- Numeric values are formatted using RPAD(TO_CHAR(#, '0..0SG', #)).
  --    TO_CHAR(#, ...) (at least in the default server locale) puts a space at
  --    the beginning of the string for numbers >= 0 and '-' for numbers < 0.
  --    'SG' pushes the sign char to the end, then RPAD cuts it off.
  -- This whole thing is for Australian bank transactions only, and generates entries for an ABA file.
  -- Currently restricted to checks to Vendor; there's no support for checks to
  --    customers or tax authorities, or for debits or corrections.
  -- This function has been adapted from the US-centric ACH formatACHChecks function.

  IF (NOT fetchMetricBool('ACHEnabled')) THEN
    RAISE EXCEPTION 'Cannot format the ABA file because the system is not configured for ABA file generation.';
  END IF;
  IF (LENGTH(COALESCE(penckey, '')) <= 0) THEN
    RAISE EXCEPTION 'Cannot format the ABA file because there is no encryption key.';
  END IF;

  SELECT * INTO _bank
  FROM bankaccnt
  WHERE (bankaccnt_id=pbankaccntid);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Could not find the bank information to create the ABA file.';
  ELSIF (NOT _bank.bankaccnt_ach_enabled) THEN
    RAISE EXCEPTION 'Cannot format the ABA file because the Bank Account % is not configured for ABA transactions.',
      _bank.bankaccnt_name;
  ELSIF (LENGTH(COALESCE(_bank.bankaccnt_routing, '')) <= 0) THEN 
    RAISE EXCEPTION 'Cannot format the ABA file because the Bank Account % has no BSB number.', _bank.bankaccnt_name;
  END IF;

  -- Check the BSB number is in the right format and then re-format for output.
  -- Valid format is \d{3}-\d{3}|\d{6}000
  IF (_bank.bankaccnt_routing ~ E'^(\\d{3})(?:-(?=\\d{3}$)|(?=\\d{3}0{3}$))(\\d{3})(0{3})?$') THEN
    _bank.bankaccnt_routing := regexp_replace(
      _bank.bankaccnt_routing,
      E'^(\\d{3})(?:-(?=\\d{3}$)|(?=\\d{3}0{3}$))(\\d{3})(0{3})?$', E'\\1-\\2'
    );
  ELSE RAISE EXCEPTION 'Cannot format the ABA file because the Bank Account % has an invalid BSB number.',
    _bank.bankaccnt_name;
  END IF;


  _filenum := LPAD(fetchNextNumber('ACHBatch'), 8, '0');

  IF (COALESCE(_bank.bankaccnt_ach_lastdate,startOfTime()) < CURRENT_DATE
    OR _bank.bankaccnt_ach_lastfileid IS NULL) THEN
    _bank.bankaccnt_ach_lastfileid = '0';
  ELSIF (_bank.bankaccnt_ach_lastfileid = '9') THEN
    _bank.bankaccnt_ach_lastfileid = 'A';
  ELSIF (_bank.bankaccnt_ach_lastfileid = 'Z') THEN
    RAISE EXCEPTION 'Cannot write % check % to an ABA file because too many files have been written for this bank already today.',
      _bank.bankaccnt_name, _check.checkhead_number;
  ELSE
    _bank.bankaccnt_ach_lastfileid = CHR(ASCII(_bank.bankaccnt_ach_lastfileid) + 1);
  END IF;
  

  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'HEADER';
  _row.achline_value := RPAD(
    RPAD('0',18)                                    -- Record Type 0 blank filled with 17 spaces
    || '01'                                         -- Reel sequence number 
    || RPAD(_bank.bankaccnt_bankname,3)             -- Approved financial instition abbreviation.
    || RPAD('',7)                                   -- blank filled
    || RPAD(fetchMetricText('ACHCompanyName'), 26)  -- Name of user supplying ABA file
    || LPAD(fetchMetricText('ACHCompanyId'),6)      -- User identification number APCA issued
    || RPAD('PAYMENT',12)                           -- description of entries on file
                                                    --  currently only use payment description
    || TO_CHAR(CURRENT_DATE,      'DDMMYY'),        -- date to be processed
    120                                             -- blank filled to 120 characters
  );
  RETURN NEXT _row;

  FOR _check IN SELECT *
    FROM checkhead
    JOIN vendinfo ON (checkhead_recip_type='V'
      AND checkhead_recip_id=vend_id
      AND vend_ach_enabled)
    JOIN curr_symbol ON (checkhead_curr_id=curr_id)
    LEFT OUTER JOIN crmacct ON (crmacct_vend_id=vend_id)
    WHERE ((checkhead_bankaccnt_id=pbankaccntid)
      AND (checkhead_amount > 0)
      AND (checkhead_id=pcheckheadid OR pcheckheadid IS NULL)
      AND NOT checkhead_posted
      AND NOT checkhead_replaced
      AND NOT checkhead_deleted
      AND NOT checkhead_void
      AND NOT checkhead_printed
      AND (LENGTH(COALESCE(checkhead_ach_batch,'')) <= 0)
      AND (curr_abbr='AUD'))
    ORDER BY checkhead_checkdate, vend_name LOOP

    IF (COALESCE(_check.checkhead_number, -1) <= 0
      AND _bank.bankaccnt_ach_genchecknum) THEN
        _check.checkhead_number := fetchNextCheckNumber(_check.checkhead_bankaccnt_id);
    END IF;

    -- Although a crmacct record is not required for used in this function
    -- this code is retained for consistancy with the original formatachchecks function.
    IF (_check.crmacct_id IS NULL) THEN
      RAISE NOTICE 'Vendor % does not have a corresponding crmacct record.',
        _check.checkhead_recip_id;
    ELSIF (_check.crmacct_type IS NULL) THEN
      RAISE NOTICE 'crmacct for vendor % does not have a valid crmacct_type.',
         _check.checkhead_recip_id;
    END IF;

    _vendnumber := CASE WHEN _check.vend_ach_use_vendinfo THEN _check.vend_number
      ELSE _check.vend_ach_indiv_number
      END;
    _vendname := CASE WHEN _check.vend_ach_use_vendinfo THEN _check.vend_name
      ELSE _check.vend_ach_indiv_name
      END;

    IF (COALESCE(_check.vend_ach_routingnumber, '') = '') THEN
      RAISE EXCEPTION 'Cannot write % check % to an ABA file because the BSB number for % has not been supplied.',
        _bank.bankaccnt_name, _check.checkhead_number, _vendnumber;
    ELSIF (COALESCE(_check.vend_ach_accntnumber, '') = '') THEN
      RAISE EXCEPTION 'Cannot write % check % to an ABA file because the account number for % has not been supplied.',
        _bank.bankaccnt_name, _check.checkhead_number, _vendnumber;
    END IF;
    _check.vend_ach_routingnumber := decrypt(setbytea(_check.vend_ach_routingnumber),
      setbytea(penckey), 'bf');
    _check.vend_ach_accntnumber   := decrypt(setbytea(_check.vend_ach_accntnumber),
      setbytea(penckey), 'bf');
    
    -- Check the BSB number is in the right format and then re-format for output.
    -- Valid format is \d{3}-\d{3}|\d{6}000
    IF (formatbytea(_check.vend_ach_routingnumber) ~ E'^(\\d{3})(?:-(?=\\d{3}$)|(?=\\d{3}0{3}$))(\\d{3})(0{3})?$') THEN
      _vendbsb := regexp_replace(
        formatbytea(_check.vend_ach_routingnumber),
        E'^(\\d{3})(?:-(?=\\d{3}$)|(?=\\d{3}0{3}$))(\\d{3})(0{3})?$', E'\\1-\\2'
      );
    ELSE RAISE EXCEPTION 'Cannot write % check % to an ABA file because the BSB number for % is not valid.',
      _bank.bankaccnt_name, _check.checkhead_number, _vendnumber;
    END IF;

    _row.achline_checkhead_id := _check.checkhead_id;
    _row.achline_batch        := _filenum;
    _row.achline_type         := 'DETAIL';

    _totaldb      := _totaldb + _check.checkhead_amount;                -- Total debits for balancing entry
    _detailcount  := _detailcount + 1;                                  -- Detail record counter (type 1)
    _totalcr      := _totalcr + _check.checkhead_amount;                -- Total credits from payments
                                                                        
    _row.achline_value := RPAD('1'                                      -- record type 1
      || _vendbsb                                                       -- vendor BSB #
      || LPAD(formatbytea(_check.vend_ach_accntnumber), 9)              -- vendor account no.
      ||' '                                                             -- withholding tax indicator
      ||'50'                                                            -- transaction code, this should be calculated.
      || LPAD(to_char(_check.checkhead_amount,'FM99999999V99'),10,'0')  -- amount
      || RPAD(_vendname,   32)                                          -- vendor name
      || RPAD('Deposit',8) || RPAD('#'  , 2) || LPAD (_filenum,8,' ')   -- Lodgement Reference
      || _bank.bankaccnt_routing                                        -- BSB #
      || RPAD(_bank.bankaccnt_accntnumber, 9)                           -- company account number
      || RPAD(fetchMetricText('ACHCompanyName'), 16)                    -- company account name
      || LPAD('', 8, '0'),                                              -- Witholding Tax Amount
      120                                                               -- line width
    );
    RETURN NEXT _row;

    UPDATE checkhead
    SET checkhead_ach_batch=_filenum,
      checkhead_number=_check.checkhead_number
    WHERE (checkhead_id=_check.checkhead_id);

  END LOOP;

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot write an ABA file for % because there are no checks pending in AUD for EFT-enabled Vendors.',
      _bank.bankaccnt_name;
  END IF;

  -- Place a final balancing detail record.
  -- Check that the balancing record actually balances.
  IF (_totalcr != _totaldb) THEN
    RAISE EXCEPTION 'Cannot write an ABA file for % because the total credits: % does not equal the total debits: %, file will not balance.',
    _bank.bankaccnt_name, _totalcr, _totaldb;
  END IF;
  

  _detailcount := _detailcount + 1;
  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'BALANCING';
  -- keep in sync with the other batchcontrol record format above
  -- THE FOLLOWING IS THE DEBIT BALANCING RECORD
  _row.achline_value := RPAD('1'                          -- record type 1
    || _bank.bankaccnt_routing                            -- Austalian BSB #
    || LPAD(_bank.bankaccnt_accntnumber, 9)               -- company account no.
    || ' '                                                -- withholding tax indicator
    || '13'                                               -- transaction code
    || to_char(_totaldb,'FM09999999V99')                  -- the balancing amount
    || RPAD(fetchMetricText('ACHCompanyName'),   32)      -- company name
    || RPAD('DIRECT DEPOSIT',18)                          
    || _bank.bankaccnt_routing                            -- Austalian BSB #
    || RPAD(_bank.bankaccnt_accntnumber, 9)               -- company account number
    || RPAD(fetchMetricText('ACHCompanyName'), 16)        -- company account name
    || LPAD('', 8, '0'),                                  -- Witholding Tax Amount
    120                                                   -- line width
  );
  RETURN NEXT _row;

  RAISE DEBUG 'formatABAChecks building TRAILER with _totaldb %, _totalcr %, _detailcount %',
               _totaldb, _totalcr, _detailcount;
  -- file control record
  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'TRAILER';
  _row.achline_value := RPAD('7'                                    -- record type 7
    || RPAD('999-999',   7)                                         -- BSB format filler
    || RPAD('' , 12)                                                -- blank
    || LPAD(to_char((_totaldb - _totalcr),'FM09999999V99'),10,'0')  -- net total amount
    || LPAD(to_char(_totalcr, 'FM09999999V99'),10,'0')              -- total credit amount
    || LPAD(to_char(_totaldb, 'FM09999999V99'),10,'0')              -- total debit amount
    || RPAD('', 24)                                                 -- blank
    || RPAD(to_char(_detailcount, 'FM000000'), 6,'0'),              -- count of type 1 records
    120                                                             -- blank fill
  );

  RETURN NEXT _row;


  UPDATE bankaccnt
  SET bankaccnt_ach_lastdate=CURRENT_DATE,
    bankaccnt_ach_lastfileid=_bank.bankaccnt_ach_lastfileid
  WHERE (bankaccnt_id=_bank.bankaccnt_id);

  RETURN;

END;

Function: public.formatachchecks(integer, integer, text)

Returns: SET OF achline

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pbankaccntid     ALIAS FOR $1;   -- all unprinted checks for this bankaccnt
  pcheckheadid     ALIAS FOR $2;   -- but if 2nd arg not null then just 1 check
  penckey          ALIAS FOR $3;
  _bank            RECORD;
  _batchcount      INTEGER := 0;
  _batchcr         NUMERIC := 0;
  _batchdate       DATE;
  _batchdb         NUMERIC := 0;
  _batchhash       INTEGER := 0;
  _check           RECORD;
  _ccdnumber       TEXT;
  _ccdname         TEXT;
  _entrycount      INTEGER := 0;
  _filenum         TEXT;
  _prevsec         TEXT;
  _row             achline%ROWTYPE;
  _rowcount        INTEGER := 0;
  _sec             TEXT;
  _serviceclass    TEXT := '200';    -- 220 = credits, 225 = debits, 200 = mixed
  _totalcr         NUMERIC := 0;
  _totaldb         NUMERIC := 0;
  _totalentrycnt   INTEGER := 0;
  _totalhash       INTEGER := 0;
  _transactionprefix TEXT;

BEGIN
  -- General notes:
  -- Numeric values are formatted using RPAD(TO_CHAR(#, '0..0SG', #)).
  --    TO_CHAR(#, ...) (at least in the default server locale) puts a space at
  --    the beginning of the string for numbers >= 0 and '-' for numbers < 0.
  --    'SG' pushes the sign char to the end, then RPAD cuts it off.
  -- This whole thing is US-centric, as that's where the NACHA is.
  -- Currently restricted to checks to Vendor; there's no support for checks to
  --    customers or tax authorities, or for debits or corrections.

  IF (NOT fetchMetricBool('ACHEnabled')) THEN
    RAISE EXCEPTION 'Cannot format the ACH file because the system is not configured for ACH file generation.';
  END IF;
  IF (LENGTH(COALESCE(penckey, '')) <= 0) THEN
    RAISE EXCEPTION 'Cannot format the ACH file because there is no encryption key.';
  END IF;

  SELECT * INTO _bank
  FROM bankaccnt
  WHERE (bankaccnt_id=pbankaccntid);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Could not find the bank information to create the ACH file.';
  ELSIF (NOT _bank.bankaccnt_ach_enabled) THEN
    RAISE EXCEPTION 'Cannot format the ACH file because the Bank Account % is not configured for ACH transactions.',
      _bank.bankaccnt_name;
  ELSIF (LENGTH(COALESCE(_bank.bankaccnt_routing, '')) <= 0) THEN 
    RAISE EXCEPTION 'Cannot format the ACH file because the Bank Account % has no routing number.',
      _bank.bankaccnt_name;
  END IF;

  _filenum := LPAD(fetchNextNumber('ACHBatch'), 8, '0');

  IF (COALESCE(_bank.bankaccnt_ach_lastdate,startOfTime()) < CURRENT_DATE
      OR _bank.bankaccnt_ach_lastfileid IS NULL) THEN
    _bank.bankaccnt_ach_lastfileid = '0';
  ELSIF (_bank.bankaccnt_ach_lastfileid = '9') THEN
    _bank.bankaccnt_ach_lastfileid = 'A';
  ELSIF (_bank.bankaccnt_ach_lastfileid = 'Z') THEN
    RAISE EXCEPTION 'Cannot write % check % to an ACH file because too many files have been written for this bank already today.',
                  _bank.bankaccnt_name, _check.checkhead_number;
  ELSE
    _bank.bankaccnt_ach_lastfileid = CHR(ASCII(_bank.bankaccnt_ach_lastfileid) + 1);
  END IF;

  _rowcount := _rowcount + 1;
  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'FILEHEADER';
  _row.achline_value := RPAD('1'
                          || '01'
                          || RPAD(CASE WHEN _bank.bankaccnt_ach_desttype = 'B' THEN ' ' || _bank.bankaccnt_routing
                                       WHEN _bank.bankaccnt_ach_desttype = 'F' THEN ' ' || _bank.bankaccnt_ach_fed_dest
                                       ELSE _bank.bankaccnt_ach_dest END, 10)
                          || RPAD(CASE WHEN _bank.bankaccnt_ach_origintype = 'B' THEN ' ' || _bank.bankaccnt_routing
                                       WHEN _bank.bankaccnt_ach_origintype = 'I' THEN formatAchCompanyId()
                                       ELSE _bank.bankaccnt_ach_origin END, 10)
                          || TO_CHAR(CURRENT_DATE,      'YYMMDD')
                          || TO_CHAR(CURRENT_TIMESTAMP, 'HH24MM')
                          || UPPER(_bank.bankaccnt_ach_lastfileid)
                          || '094'
                          || '10'
                          || '1'
                          || RPAD(CASE WHEN _bank.bankaccnt_ach_desttype = 'B' THEN _bank.bankaccnt_bankname
                                       WHEN _bank.bankaccnt_ach_desttype = 'F' THEN 'Federal Reserve'
                                       ELSE _bank.bankaccnt_ach_destname END, 23)
                          || RPAD(CASE WHEN _bank.bankaccnt_ach_origintype = 'B' THEN ' ' || _bank.bankaccnt_bankname
                                       WHEN _bank.bankaccnt_ach_origintype = 'I' THEN fetchMetricText('ACHCompanyName')
                                       ELSE _bank.bankaccnt_ach_originname END, 23)
                          || RPAD(_filenum, 8),
                          94);
  RETURN NEXT _row;

  FOR _check IN SELECT *
                FROM checkhead
                JOIN vendinfo ON (checkhead_recip_type='V'
                              AND checkhead_recip_id=vend_id
                              AND vend_ach_enabled)
                JOIN curr_symbol ON (checkhead_curr_id=curr_id)
                LEFT OUTER JOIN crmacct ON (crmacct_vend_id=vend_id)
                WHERE ((checkhead_bankaccnt_id=pbankaccntid)
                   AND (checkhead_amount > 0)
                   AND (checkhead_id=pcheckheadid OR pcheckheadid IS NULL)
                   AND NOT checkhead_posted
                   AND NOT checkhead_replaced
                   AND NOT checkhead_deleted
                   AND NOT checkhead_void
                   AND NOT checkhead_printed
                   AND (LENGTH(COALESCE(checkhead_ach_batch,'')) <= 0)
                   AND (curr_abbr='USD'))
                ORDER BY checkhead_checkdate, vend_name LOOP

    IF (COALESCE(_check.checkhead_number, -1) <= 0
        AND _bank.bankaccnt_ach_genchecknum) THEN
      _check.checkhead_number := fetchNextCheckNumber(_check.checkhead_bankaccnt_id);
    END IF;

    _prevsec := _sec;

    IF (_check.crmacct_type = 'I') THEN
      _sec := 'PPD';
    ELSE
      _sec := 'CCD';
      IF (_check.crmacct_id IS NULL) THEN
        RAISE NOTICE 'Vendor % does not have a corresponding crmacct record.',
                     _check.checkhead_recip_id;
      ELSIF (_check.crmacct_type IS NULL) THEN
        RAISE NOTICE 'crmacct for vendor % does not have a valid crmacct_type.',
                     _check.checkhead_recip_id;
      END IF;
    END IF;

    _ccdnumber := CASE WHEN _check.vend_ach_use_vendinfo THEN _check.vend_number
                       ELSE _check.vend_ach_indiv_number
                  END;
    _ccdname := CASE WHEN _check.vend_ach_use_vendinfo THEN _check.vend_name
                     ELSE _check.vend_ach_indiv_name
                END;

    IF (COALESCE(_check.vend_ach_routingnumber, '') = '') THEN
      RAISE EXCEPTION 'Cannot write % check % to an ACH file because the routing number for % has not been supplied.',
                  _bank.bankaccnt_name, _check.checkhead_number, _ccdnumber;
    ELSIF (COALESCE(_check.vend_ach_accntnumber, '') = '') THEN
      RAISE EXCEPTION 'Cannot write % check % to an ACH file because the account number for % has not been supplied.',
                  _bank.bankaccnt_name, _check.checkhead_number, _ccdnumber;
    END IF;
    _check.vend_ach_routingnumber := decrypt(setbytea(_check.vend_ach_routingnumber),
                                         setbytea(penckey), 'bf');
    _check.vend_ach_accntnumber   := decrypt(setbytea(_check.vend_ach_accntnumber),
                                         setbytea(penckey), 'bf');
    _transactionprefix := CASE WHEN (_check.vend_ach_accnttype = 'K') THEN '2'
                               WHEN (_check.vend_ach_accnttype = 'C') THEN '3'
                          END;

    -- create separate batches for each check date and for PPD vs CCD
    IF (COALESCE(_batchdate, startOfTime()) != _check.checkhead_checkdate
        OR (_prevsec != _sec)) THEN
      IF (_batchcount > 0) THEN
        _rowcount := _rowcount + 1;
        _row.achline_checkhead_id := NULL;
        _row.achline_batch := _filenum;
        _row.achline_type := 'BATCHCONTROL';
        -- keep in sync with the other batchcontrol record format below
        _row.achline_value := RPAD('8'
                                || _serviceclass
                                || RPAD(TO_CHAR(_entrycount, '000000SG'), 6)
                                || RPAD(TO_CHAR(_batchhash % 10000000000,
                                                '0000000000SG'), 10)
                                || RPAD(TO_CHAR(_batchdb, '0000000000V99SG'), 12)
                                || RPAD(TO_CHAR(_batchcr, '0000000000V99SG'), 12)
                                || RPAD(formatAchCompanyId(), 10)
                                || RPAD(' ', 19)
                                || RPAD(' ',  6)
                                || RPAD(_bank.bankaccnt_routing, 8)
                                || RPAD(TO_CHAR(_batchcount, '0000000SG'), 7),
                                94);
        RETURN NEXT _row;
      END IF;

      _batchhash     := 0;
      _batchcr       := 0;
      _batchdb       := 0;
      _batchdate     := _check.checkhead_checkdate;
      _entrycount    := 0;
      _rowcount      := _rowcount + 1;
      _batchcount    := _batchcount + 1;
      _row.achline_checkhead_id := NULL;
      _row.achline_batch := _filenum;
      _row.achline_type := 'BATCHHEADER';

      -- effective entry date = 1 or 2 banking days after the banking day
      -- of processing (the following accounts for weekends but not holidays)

      _row.achline_value := RPAD('5'
                              || _serviceclass
                              || RPAD(fetchMetricText('ACHCompanyName'), 16)
                              || RPAD('', 20)   -- TODO: find a use
                              || RPAD(formatAchCompanyId(), 10)
                              || _sec
                              || RPAD('xTuple ERP', 10)
                              || TO_CHAR(_check.checkhead_checkdate, 'YYMMDD')
                              || TO_CHAR(CURRENT_DATE +
                                         COALESCE(_bank.bankaccnt_ach_leadtime,1) +
                                         CASE WHEN EXTRACT(DOW FROM CURRENT_DATE) = 5 THEN 2
                                              WHEN EXTRACT(DOW FROM CURRENT_DATE) = 6 THEN 1
                                              ELSE 0 END,
                                         'YYMMDD')
                              || RPAD('', 3)
                              || '1'
                              || RPAD(_bank.bankaccnt_routing, 8)
                              || RPAD(TO_CHAR(_batchcount, '0000000SG'), 7),
                              94);
      RETURN NEXT _row;
    END IF;

    _row.achline_checkhead_id := _check.checkhead_id;
    _row.achline_batch        := _filenum;
    _row.achline_type         := _sec;

    IF (_sec = 'CCD' OR _sec = 'PPD') THEN
      _rowcount      := _rowcount + 1;
      _entrycount    := _entrycount + 1;
      _totalentrycnt := _totalentrycnt + 1;
      _batchhash     := _batchhash + CAST(SUBSTRING(_bank.bankaccnt_routing FOR 8) AS INTEGER);
      _totalhash     := _totalhash + CAST(SUBSTRING(_bank.bankaccnt_routing FOR 8) AS INTEGER);
      _batchdb       := _batchdb + _check.checkhead_amount;
      _totaldb       := _totaldb + _check.checkhead_amount;

      _row.achline_value := RPAD('6'
                              || _transactionprefix || '7'              -- debit
                              || RPAD(_bank.bankaccnt_routing,      9)  -- 2 fields
                              || RPAD(_bank.bankaccnt_accntnumber, 17)
                              || RPAD(TO_CHAR(_check.checkhead_amount,
                                              '00000000V99SG'), 10)
                              || RPAD(fetchMetricText('ACHCompanyId'),   15)
                              || RPAD(fetchMetricText('ACHCompanyName'), 22)
                              || RPAD(TO_CHAR(_check.checkhead_id % 100, '00SG'),
                                      2)        -- last 2 digits of checkhead_id
                              || '0'
                              || RPAD(_bank.bankaccnt_routing, 9)  -- split field
                              || RPAD(TO_CHAR(_entrycount, '000000SG'), 15-9),
                              94);
      RETURN NEXT _row;

      _rowcount      := _rowcount + 1;
      _entrycount    := _entrycount + 1;
      _totalentrycnt := _totalentrycnt + 1;
      _batchhash     := _batchhash + CAST(SUBSTRING(formatbytea(_check.vend_ach_routingnumber) FOR 8) AS INTEGER);
      _totalhash     := _totalhash + CAST(SUBSTRING(formatbytea(_check.vend_ach_routingnumber) FOR 8) AS INTEGER);
      _totalcr       := _totalcr + _check.checkhead_amount;
      _batchcr       := _batchcr + _check.checkhead_amount;
      _row.achline_value := RPAD('6'
                              || _transactionprefix || '2'              -- credit
                              || RPAD(formatbytea(_check.vend_ach_routingnumber), 9)   -- 2 fields
                              || RPAD(formatbytea(_check.vend_ach_accntnumber), 17)
                              || RPAD(TO_CHAR(_check.checkhead_amount,
                                              '00000000V99SG'), 10)
                              || RPAD(_ccdnumber, 15)
                              || RPAD(_ccdname,   22)
                              || RPAD(TO_CHAR(_check.checkhead_id % 100, '00SG'),
                                      2)        -- last 2 digits of checkhead_id
                              || '0'
                              || RPAD(_bank.bankaccnt_routing, 9)  -- split field
                              || RPAD(TO_CHAR(_entrycount, '000000SG'), 15-9),
                              94);
      RETURN NEXT _row;

    ELSE
      RAISE EXCEPTION 'Cannot write % check % to an ACH file because % is not a supported SEC code.',
                    _bank.bankaccnt_name, _check.checkhead_number, _sec;
    END IF;

    UPDATE checkhead
    SET checkhead_ach_batch=_filenum,
        checkhead_number=_check.checkhead_number
    WHERE (checkhead_id=_check.checkhead_id);

  END LOOP;

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot write an ACH file for % because there are no checks pending in USD for ACH-enabled Vendors.',
                    _bank.bankaccnt_name;
  END IF;

  -- place a final batch control record
  IF (_batchcount > 0) THEN
    _rowcount := _rowcount + 1;
    _row.achline_checkhead_id := NULL;
    _row.achline_batch := _filenum;
    _row.achline_type := 'BATCHCONTROL';
    -- keep in sync with the other batchcontrol record format above
    _row.achline_value := RPAD('8'
                            || _serviceclass
                            || RPAD(TO_CHAR(_entrycount, '000000SG'), 6)
                            || RPAD(TO_CHAR(_batchhash % 10000000000,
                                            '0000000000SG'), 10)
                            || RPAD(TO_CHAR(_batchdb, '0000000000V99SG'), 12)
                            || RPAD(TO_CHAR(_batchcr, '0000000000V99SG'), 12)
                            || RPAD(formatAchCompanyId(), 10)
                            || RPAD(' ', 19)
                            || RPAD(' ',  6)
                            || RPAD(_bank.bankaccnt_routing, 8)
                            || RPAD(TO_CHAR(_batchcount, '0000000SG'), 7),
                            94);
    RETURN NEXT _row;
  END IF;

  -- and end with a file control record
  _rowcount := _rowcount + 1;
  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'FILECONTROL';
  _row.achline_value := RPAD('9'
                          || RPAD(TO_CHAR(_batchcount,    '000000SG'),   6)
                          || RPAD(TO_CHAR(_rowcount,      '000000SG'),   6)
                          || RPAD(TO_CHAR(_totalentrycnt, '00000000SG'), 8)
                          || RPAD(TO_CHAR(_totalhash % 10000000000,
                                          '0000000000SG'), 10)
                          || RPAD(TO_CHAR(_totaldb, '0000000000V99SG'), 12)
                          || RPAD(TO_CHAR(_totalcr, '0000000000V99SG'), 12)
                          || RPAD('', 39),
                          94);

  RETURN NEXT _row;

  -- file must be a multiple of 10 lines long
  _row.achline_checkhead_id := NULL;
  _row.achline_batch := _filenum;
  _row.achline_type := 'BLOCKFILL';
  WHILE (_rowcount % 10 > 0) LOOP
    _rowcount := _rowcount + 1;
    _row.achline_value := RPAD('99999999999999999999'
                            || '99999999999999999999'
                            || '99999999999999999999'
                            || '99999999999999999999'
                            || '99999999999999999999', 94);
    RETURN NEXT _row;
  END LOOP;

  UPDATE bankaccnt
  SET bankaccnt_ach_lastdate=CURRENT_DATE,
      bankaccnt_ach_lastfileid=_bank.bankaccnt_ach_lastfileid
  WHERE (bankaccnt_id=_bank.bankaccnt_id);

  RETURN;

END;

Function: public.formatachcompanyid()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN CASE WHEN fetchMetricText('ACHCompanyIdType') = 'D' THEN '3'
              WHEN fetchMetricText('ACHCompanyIdType') = 'E' THEN '1'
              WHEN fetchMetricText('ACHCompanyIdType') = 'O' THEN '9'
         END ||
         CASE WHEN fetchMetricText('ACHCompanyIdType') = 'D' OR
                   fetchMetricText('ACHCompanyIdType') = 'E' THEN
                 REPLACE(fetchMetricText('ACHCompanyId'), '-', '')
              ELSE fetchMetricText('ACHCompanyId')
         END;
END;

Function: public.formataddr(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAddrId       ALIAS FOR $1;
  _return       TEXT;

BEGIN
  -- US conventions
  SELECT formatAddr(addr_line1, addr_line2, addr_line3,
                    addr_city || ', ' || addr_state || ' ' || addr_postalcode,
                    addr_country) INTO _return
  FROM addr
  WHERE (addr_id=pAddrId);

  RETURN _return;
END;

Function: public.formataddr(text, text, text, text, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  f_addr1 ALIAS FOR $1;
  f_addr2 ALIAS FOR $2;
  f_addr3 ALIAS FOR $3;
  csz     ALIAS FOR $4;
  line    ALIAS FOR $5;

BEGIN
  RETURN formatAddr(f_addr1, f_addr2, f_addr3, csz, '', line);
END;

Function: public.formataddr(text, text, text, text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  f_addr1 ALIAS FOR $1;
  f_addr2 ALIAS FOR $2;
  f_addr3 ALIAS FOR $3;
  csz     ALIAS FOR $4;
  country ALIAS FOR $5;
  addr TEXT:='';

BEGIN

  IF (LENGTH(TRIM(both from f_addr1)) > 0) THEN
    addr:=f_addr1;
  END IF;

  IF (LENGTH(TRIM(both from f_addr2)) > 0)  THEN
        IF (LENGTH(TRIM(both from addr)) > 0) THEN
                addr:=addr || E'\n';
        END IF;
    addr:=addr || f_addr2;
  END IF;

  IF (LENGTH(TRIM(both from f_addr3)) > 0)  THEN
        IF (LENGTH(TRIM(both from addr)) > 0) THEN
                addr:=addr || E'\n';
        END IF;
    addr:=addr || f_addr3;
  END IF;

  IF (LENGTH(TRIM(both from csz)) > 0)  THEN
        IF (LENGTH(TRIM(both from addr)) > 0) THEN
                addr:=addr || E'\n';
        END IF;
    addr:=addr || csz;
  END IF;

  IF (LENGTH(TRIM(both from country)) > 0)  THEN
        IF (LENGTH(TRIM(both from addr)) > 0) THEN
                addr:=addr || E'\n';
        END IF;
    addr:=addr || country;
  END IF;

  RETURN addr;

END;

Function: public.formataddr(text, text, text, text, text, integer)

Returns: text

Language: PLPGSQL

 
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  f_addr1 ALIAS FOR $1;
  f_addr2 ALIAS FOR $2;
  f_addr3 ALIAS FOR $3;
  csz     ALIAS FOR $4;
  country ALIAS FOR $5;
  line    ALIAS FOR $6;

  i int:=0;

BEGIN

  IF (LENGTH(TRIM(both from f_addr1)) > 0) THEN
    i:=i+1;
  END IF;

  IF (i=line) THEN
    RETURN f_addr1;
  END IF;

  IF (LENGTH(TRIM(both from f_addr2)) > 0)  THEN
    i:=i+1;
  END IF;

  IF (i=line) THEN
    RETURN f_addr2;
  END IF;

  IF (LENGTH(TRIM(both from f_addr3)) > 0) THEN
    i:=i+1;
  END IF;

  IF (i=line) THEN
    RETURN f_addr3;
  END IF;

  IF (LENGTH(TRIM(both from csz)) > 0) THEN
    i:=i+1;
  END IF;

  IF (i=line) THEN
    RETURN csz;
  END IF;

  IF (LENGTH(TRIM(both from country)) > 0) THEN
    i:=i+1;
  END IF;

  IF (i=line) THEN
    RETURN country;
  END IF;

  RETURN ' ';

END;

Function: public.formatboolyn(boolean)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE pBool ALIAS FOR $1;
BEGIN
  IF (pBool) THEN
    RETURN 'Yes';
  ELSE
    RETURN 'No';
  END IF;
END;

Function: public.formatbooseq(integer, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pBooitemSeqId ALIAS FOR $2;
  _result TEXT;
  
BEGIN

  IF (fetchMetricBool('Routings')) THEN
    SELECT booitem_seqnumber::text INTO _result
    FROM xtmfg.booitem(pItemid)
    WHERE (booitem_seq_id=pBooitemSeqId);

    RETURN _result;
  ELSE
    RETURN NULL;
  END IF;

END;

Function: public.formatbytea(bytea)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pField ALIAS FOR $1;
  output_field TEXT;

BEGIN

  output_field := pField;

  RETURN output_field;

END;

Function: public.formatccdashes(text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCCard ALIAS FOR $1;
  pCCardType ALIAS FOR $2;
  _returnCard text;
  card_length integer;

BEGIN

  IF (pCCardType = 'A')  THEN
    _returnCard := pCCard;
    RETURN _returnCard;
  END IF;

  card_length := length(pCcard);

  if (card_length = 16) THEN
    _returnCard := substr(pCCard, 1, 4) || '-' || substr(pCCard, 5, 4) || '-' || substr(pCCard, 9, 4) || '-' || substr(pCCard, 13, 4);
  ELSE
    _returnCard := substr(pCCard, 1, 4) || '-' || substr(pCCard, 5, 4) || '-' || substr(pCCard, 9, 4) || '-' || substr(pCCard, 13, 1);
  END IF;

  RETURN _returnCard;

END;

Function: public.formatccnumber(bytea)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCcardnum ALIAS FOR $1;
  card_length INTEGER;
  output_cardnum TEXT;

BEGIN

  card_length := length(pCcardnum);

  IF (card_length = 13) THEN
    output_cardnum := '*********' || substr(pCcardnum, 10, 4);  
  END IF;

  IF (card_length = 14) THEN
    output_cardnum := '**********' || substr(pCcardnum, 11, 4);  
  END IF;

  IF (card_length = 15) THEN
    output_cardnum := '***********' || substr(pCcardnum, 12, 4);  
  END IF;

  IF (card_length = 16) THEN
    output_cardnum := '************' || substr(pCcardnum, 13, 4);  
  END IF;

  RETURN output_cardnum;

END;

Function: public.formatccnumber(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCcardnum ALIAS FOR $1;
  card_length INTEGER;
  output_cardnum TEXT;

BEGIN

  card_length := length(pCcardnum);

  IF (card_length = 13) THEN
    output_cardnum := '*********' || substr(pCcardnum, 10, 4);  
  END IF;

  IF (card_length = 14) THEN
    output_cardnum := '**********' || substr(pCcardnum, 11, 4);  
  END IF;

  IF (card_length = 15) THEN
    output_cardnum := '***********' || substr(pCcardnum, 12, 4);  
  END IF;

  IF (card_length = 16) THEN
    output_cardnum := '************' || substr(pCcardnum, 13, 4);  
  END IF;

  RETURN output_cardnum;

END;

Function: public.formatcntctname(integer)

Returns: text

Language: PLPGSQL

 
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntctId ALIAS FOR $1;
  _r RECORD;
  _rows NUMERIC;

BEGIN

  SELECT cntct_honorific, cntct_first_name, cntct_middle, 
    cntct_last_name, cntct_suffix INTO _r
  FROM cntct
  WHERE (cntct_id=pCntctId);

  GET DIAGNOSTICS _rows = ROW_COUNT;
  IF (_rows = 0) THEN
    RETURN '';
  END IF;

  RETURN formatCntctName(_r.cntct_honorific, _r.cntct_first_name, _r.cntct_middle, _r.cntct_last_name, _r.cntct_suffix);

END;

Function: public.formatcntctname(text, text, text, text, text)

Returns: text

Language: PLPGSQL

 
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pHonorific ALIAS FOR $1;
  pFirstName ALIAS FOR $2;
  pMiddle ALIAS FOR $3;
  pLastName ALIAS FOR $4;
  pSuffix ALIAS FOR $5;
  _name TEXT := '';

BEGIN

  IF (LENGTH(TRIM(both from COALESCE(pHonorific,''))) > 0) THEN
    IF (POSITION('.' IN COALESCE(pHonorific, '')) > 0) THEN
      _name:= pHonorific;
    ELSE
      _name:= pHonorific || '.';
    END IF;
  END IF;

  IF (LENGTH(TRIM(both from COALESCE(pFirstName,''))) > 0)  THEN
        IF (LENGTH(TRIM(both from _name)) > 0) THEN
                _name:=_name || ' ';
        END IF;
    _name:=_name || pFirstName;
  END IF;

  IF (LENGTH(TRIM(both from COALESCE(pMiddle,''))) > 0)  THEN
        IF (LENGTH(TRIM(both from _name)) > 0) THEN
                _name:=_name || ' ';
        END IF;
    IF (POSITION('.' IN COALESCE(pHonorific, '')) > 0) THEN
      _name:=_name || pMiddle;
    ELSE
      _name:=_name || pMiddle || '.';
    END IF;
  END IF;

  IF (LENGTH(TRIM(both from COALESCE(pLastName,''))) > 0)  THEN
        IF (LENGTH(TRIM(both from _name)) > 0) THEN
                _name:=_name || ' ';
        END IF;
    _name:=_name || pLastName;
  END IF;

  IF (LENGTH(TRIM(both from COALESCE(pSuffix,''))) > 0)  THEN
        IF (LENGTH(TRIM(both from _name)) > 0) THEN
                _name:=_name || ' ';
        END IF;
    _name:=_name || pSuffix;
  END IF;

  RETURN _name;

END;

Function: public.formatcost(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'cost');
END;

Function: public.formatcounttagbarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCnttagid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138CTXX' ||
           LTRIM(TO_CHAR(LENGTH(invcnt_tagnumber), '00')) || invcnt_tagnumber ) INTO _barcode
  FROM invcnt
  WHERE (invcnt_id=pCnttagid);

  RETURN _barcode;

END;

Function: public.formatcreditmemonumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;

BEGIN
  RETURN ( SELECT COALESCE(cmhead_number::TEXT, '')
           FROM cmhead
           WHERE (cmhead_id=pCmheadid) );
END;

Function: public.formatdate(date)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT TO_CHAR($1, COALESCE((SELECT locale_dateformat
                             FROM locale, usr
                             WHERE ((usr_locale_id=locale_id)
                              AND (usr_username=getEffectiveXtUser())) ),
                            'yyyy-mm-dd') ) AS result

Function: public.formatdate(date, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pDate ALIAS FOR $1;
  pString ALIAS FOR $2;

BEGIN

  IF ( (pDate = startOfTime()) OR
       (pDate = endOfTime()) OR
       (pDate IS NULL) ) THEN
    RETURN pString;
  ELSE
    RETURN formatDate(pDate);
  END IF;

END;

Function: public.formatdate(timestamp with time zone)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT TO_CHAR($1, COALESCE((SELECT locale_dateformat
                             FROM locale, usr
                             WHERE ((usr_locale_id=locale_id)
                              AND (usr_username=getEffectiveXtUser())) ),
                            'yyyy-mm-dd' )) AS result

Function: public.formatdatetime(timestamp with time zone)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT TO_CHAR($1, COALESCE((SELECT locale_timestampformat
                             FROM locale, usr
                             WHERE ((usr_locale_id=locale_id)
                              AND (usr_username=getEffectiveXtUser())) ),
                            'yyyy-mm-dd HH24:MI:SS')) AS result

Function: public.formatdatetime(timestamp without time zone)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT TO_CHAR($1, COALESCE((SELECT locale_timestampformat
                             FROM locale, usr
                             WHERE ((usr_locale_id=locale_id)
                              AND (usr_username=getEffectiveXtUser())) ),
                            'yyyy-mm-dd HH24:MI:SS')) AS result

Function: public.formatextprice(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'extprice');
END;

Function: public.formatflitemdescrip(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlitemId ALIAS FOR $1;
  _x RECORD;
  _descrip TEXT;

BEGIN
  SELECT flitem_accnt_id, flitem_company, flitem_profit, flitem_number,
        flitem_sub, flitem_type, flitem_subaccnttype_code,
        accnt_id, accnt_descrip INTO _x
  FROM flitem LEFT OUTER JOIN accnt
        ON flitem_accnt_id=accnt_id
  WHERE flitem_id=pFlitemId;

  IF _x.flitem_accnt_id > -1 THEN

    SELECT (formatGLAccount(_x.accnt_id) || '-' || _x.accnt_descrip) INTO _descrip;

  ELSE

    _descrip:='';

    IF _x.flitem_type = 'A' THEN
      _descrip:='Type=' || 'Asset';
      ELSE IF _x.flitem_type='L' THEN
        _descrip:='Type=' || 'Liability';
        ELSE IF _x.flitem_type='R' THEN
          _descrip:='Type=' || 'Revenue';
          ELSE IF _x.flitem_type='E' THEN
            _descrip:='Type=' || 'Expense';
            ELSE IF _x.flitem_type='Q' THEN
              _descrip:='Type=' || 'Equity';
            END IF;
          END IF;
        END IF;
      END IF;
    END IF;

    IF _x.flitem_subaccnttype_code <> 'All' THEN
      IF (LENGTH(TRIM(both from _descrip)) > 0) THEN
        _descrip:=_descrip || ', ';
      END IF;
      _descrip:=_descrip || 'Sub Accnt Type=' || _x.flitem_subaccnttype_code;
    END IF;

    IF _x.flitem_company <> 'All' THEN
      IF (LENGTH(TRIM(both from _descrip)) > 0) THEN
        _descrip:=_descrip || ', ';
      END IF;
      _descrip:=_descrip || 'Company=' || _x.flitem_company;
    END IF;

    IF _x.flitem_profit <> 'All' THEN
      IF (LENGTH(TRIM(both from _descrip)) > 0) THEN
        _descrip:=_descrip || ', ';
      END IF;
      _descrip:=_descrip || 'Profit=' || _x.flitem_profit;
    END IF;

    IF _x.flitem_number <> 'All' THEN
      IF (LENGTH(TRIM(both from _descrip)) > 0) THEN
        _descrip:=_descrip || ', ';
      END IF;
      _descrip:=_descrip || 'Number=' || _x.flitem_number;
    END IF;

    IF _x.flitem_sub <> 'All' THEN
      IF (LENGTH(TRIM(both from _descrip)) > 0) THEN
        _descrip:=_descrip || ', ';
      END IF;
      _descrip:=_descrip || 'Sub Accnt=' || _x.flitem_sub;
    END IF;
  END IF;

  RETURN _descrip;

END;

Function: public.formatglaccount(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntid ALIAS FOR $1;
  _accnt RECORD;

BEGIN

  SELECT COALESCE(accnt_company, '') AS accnt_company,
         COALESCE(accnt_profit, '') AS accnt_profit,
         accnt_number,
         COALESCE(accnt_sub, '') AS accnt_sub INTO _accnt
  FROM accnt
  WHERE (accnt_id=pAccntid);

  IF (NOT FOUND) THEN
    RETURN 'Error';
  END IF;

  RETURN formatGlAccount(_accnt.accnt_company, _accnt.accnt_profit, _accnt.accnt_number, _accnt.accnt_sub);

END;

Function: public.formatglaccount(text, text, text, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCompany ALIAS FOR $1;
  pProfit ALIAS FOR $2;
  pNumber ALIAS FOR $3;
  pSub    ALIAS FOR $4;
  _number TEXT := '';

BEGIN

  IF ( ( SELECT metric_value::INTEGER
         FROM metric
         WHERE (metric_name='GLCompanySize') ) > 0 ) THEN
    _number := pCompany || '-';
  END IF;

  IF ( ( SELECT metric_value::INTEGER
         FROM metric
         WHERE (metric_name='GLProfitSize') ) > 0 ) THEN
    _number := _number || pProfit || '-';
  END IF;

  _number := _number || pNumber;

  IF ( ( SELECT metric_value::INTEGER
         FROM metric
         WHERE (metric_name='GLSubaccountSize') ) > 0 ) THEN
    _number := _number || '-' || pSub;
  END IF;

  RETURN _number;

END;

Function: public.formatglaccountlong(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntid ALIAS FOR $1;
  _result TEXT;

BEGIN

  SELECT (formatGLAccount(accnt_id) || '-' || accnt_descrip) INTO _result
  FROM accnt
  WHERE (accnt_id=pAccntid);

  RETURN _result;

END;

Function: public.formatindent(text, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pText ALIAS FOR $1;
  pIndent ALIAS FOR $2;
  _i INTEGER;
  _result TEXT;

BEGIN
  _result := '';
  _i := 0;

  WHILE _i < pIndent LOOP
    _result := _result || '  ';
    _i := _i + 1;
  END LOOP;

  _result := _result || pText;
  RETURN _result;
END;

Function: public.formatinterval(interval)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT TO_CHAR($1, ( SELECT locale_intervalformat
                       FROM locale, usr
                       WHERE ((usr_locale_id=locale_id)
                         AND  (usr_username=getEffectiveXtUser())) ) ) AS result

Function: public.formatinterval(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT TO_CHAR(('@ ' || trunc($1) || ' min ' ||
                             ($1 - trunc($1)) * 60 || ' sec')::INTERVAL,
                 ( SELECT locale_intervalformat
                       FROM locale, usr
                       WHERE ((usr_locale_id=locale_id)
                         AND  (usr_username=getEffectiveXtUser())) ) ) AS result

Function: public.formatinvcnumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;

BEGIN
  RETURN ( SELECT COALESCE(cobmisc_invcnumber::TEXT, '')
           FROM cobmisc
           WHERE (cobmisc_id=pCobmiscid) );
END;

Function: public.formatitemsitebarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138ISXX' ||
           LTRIM(TO_CHAR(LENGTH(item_number), '00')) || LENGTH(warehous_code)::TEXT ||
           item_number || warehous_code ) INTO _barcode
  FROM itemsite, item, whsinfo
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_warehous_id=warehous_id)
   AND (itemsite_id=pItemsiteid) );

  RETURN _barcode;

END;

Function: public.formatlocationbarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138LOXX' ||
           LENGTH(warehous_code)::TEXT || LTRIM(TO_CHAR(LENGTH(location_name::TEXT), '00')) ||
           warehous_code || location_name ) INTO _barcode
  FROM location, whsinfo
  WHERE ( (location_warehous_id=warehous_id)
   AND (location_id=pLocationid) );

  RETURN _barcode;

END;

Function: public.formatlocationcontentsbarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138LOCN' ||
           LENGTH(warehous_code)::TEXT || LTRIM(TO_CHAR(LENGTH(location_name), '00')) ||
           warehous_code || location_name ) INTO _barcode
  FROM location, whsinfo
  WHERE ( (location_warehous_id=warehous_id)
   AND (location_id=pLocationid) );

  RETURN _barcode;

END;

Function: public.formatlocationissuebarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138LOIS' ||
           LENGTH(warehous_code)::TEXT || LTRIM(TO_CHAR(LENGTH(location_name), '00')) ||
           warehous_code || location_name ) INTO _barcode
  FROM location, whsinfo
  WHERE ( (location_warehous_id=warehous_id)
   AND (location_id=pLocationid) );

  RETURN _barcode;

END;

Function: public.formatlocationname(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  _name TEXT;
  _r RECORD;

BEGIN

  SELECT location_aisle, location_rack,
         location_bin, location_name INTO _r
  FROM location
  WHERE (location_id=pLocationid);
  IF (FOUND) THEN
    IF (_r.location_aisle IS NOT NULL) THEN
      _name := _r.location_aisle;
    ELSE
      _name := '';
    END IF;

    IF (_r.location_rack IS NOT NULL) THEN
      _name := (_name || _r.location_rack);
    END IF;

    IF (_r.location_bin IS NOT NULL) THEN
      _name := (_name || _r.location_bin);
    END IF;

    IF (_r.location_name IS NOT NULL) THEN
      _name := (_name || _r.location_name);
    END IF;

    RETURN _name;
  ELSE
    RETURN 'N/A';
  END IF;

END;

Function: public.formatlotserialnumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLotSerialId ALIAS FOR $1;
  _lotserial TEXT;

BEGIN
  --See if lot serial control turned on (Postbooks will not ever have this)
  IF (fetchmetricbool('LotSerialControl')) THEN
    SELECT ls_number INTO _lotserial
    FROM ls
    WHERE (ls_id=pLotSerialId);
  END IF;

  RETURN COALESCE(_lotserial,'');

END;

Function: public.formatmoney(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'curr');
END;

Function: public.formatnumeric(numeric, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _value        NUMERIC := $1;
  _type         TEXT    := LOWER(COALESCE($2, 'curr'));
  _abs          NUMERIC;
  _magnitudecnt NUMERIC(1000);
  _wholefmt     TEXT    := '0';
  _scale        INTEGER;
  _neg          TEXT;
  _decimal      TEXT;
  _group        TEXT;
  _string       TEXT;
  _debug        BOOL := false;
  _r            RECORD;

BEGIN
  -- If the value passed in is NULL then we want to pass back an empty string
  IF(_value IS NULL) THEN
    RETURN '';
  END IF;

  SELECT * INTO _r
  FROM locale, usr
  WHERE ((usr_locale_id=locale_id)
     AND (usr_username=getEffectiveXtUser()));

  _decimal := COALESCE(SUBSTRING(_r.locale_qtyformat FROM 1 FOR 1), '.');
  _neg     := COALESCE(SUBSTRING(_r.locale_qtyformat FROM 2 FOR 1), '-');
  _group   := COALESCE(SUBSTRING(_r.locale_qtyformat FROM 3 FOR 1), ',');

  _scale   := CASE WHEN _type = 'cost'       THEN _r.locale_cost_scale
                   WHEN _type = 'extprice'   THEN _r.locale_extprice_scale
                   WHEN _type = 'percent'    THEN _r.locale_percent_scale
                   WHEN _type = 'purchprice' THEN _r.locale_purchprice_scale
                   WHEN _type = 'qty'        THEN _r.locale_qty_scale
                   WHEN _type = 'qtyper'     THEN _r.locale_qtyper_scale
                   WHEN _type = 'salesprice' THEN _r.locale_salesprice_scale
                   WHEN _type = 'uomratio'   THEN _r.locale_uomratio_scale
                   WHEN _type = 'weight'     THEN _r.locale_weight_scale
                   WHEN SUBSTRING(_type FOR 4) = 'curr' THEN _r.locale_curr_scale
                   ELSE 2
              END;

  _value        := round(_value, _scale);
  _abs          := ABS(_value);
  _magnitudecnt := TRUNC(_abs / 10);

  IF (_debug) THEN
    RAISE NOTICE '_value % _abs % _scale % _neg % _decimal % _group % ',
                 _value, _abs, _scale, _decimal, _group, _scale;
  END IF;

  IF (_value < 0) THEN
    _string := _neg;
  ELSE
    _string := '';
  END IF;

  WHILE (_magnitudecnt >= 1) LOOP
    _magnitudecnt := TRUNC(_magnitudecnt / 10);
    IF (LENGTH(_wholefmt) % 3 = 0) THEN
      _wholefmt := '"' || _group || '"' || _wholefmt;
    END IF;
    _wholefmt := '9' || _wholefmt;
  END LOOP;

  IF (_scale > 0) THEN
    _abs := (_abs * (10 ^ _scale));
    _abs := TRUNC(_abs);
    _wholefmt := _wholefmt || '"' || _decimal || '"' || REPEAT('0', _scale);
  END IF;

  _wholefmt := 'FM' || _wholefmt;
  _string := _string || to_char(_abs, _wholefmt);

  RETURN _string;
END;

Function: public.formatperiodname(integer, bpchar)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodId ALIAS FOR $1;
  pInterval ALIAS FOR $2;
  _result TEXT;

BEGIN

--...for Month

   IF (pInterval='M') THEN
        SELECT
          (CASE
                      WHEN period_name='' THEN
                        formatdate(period_start) || '-' || formatdate(period_end)
                      ELSE period_name
          END) INTO _result
        FROM period
        WHERE (period_id=pPeriodId);

        RETURN _result;

--...for Quarter

        ELSE IF (pInterval='Q') THEN
                SELECT
                        ('Q' || period_quarter || '-' || EXTRACT(year from yearperiod_end)) INTO _result
                FROM period, yearperiod
                WHERE ((period_id=pPeriodId)
                AND (period_yearperiod_id=yearperiod_id));

                RETURN _result;
--...for Year
        ELSE
                SELECT
                        EXTRACT(year FROM yearperiod_end) INTO _result
                FROM period,yearperiod
                WHERE ((period_id=pPeriodId)
                AND (period_yearperiod_id=yearperiod_id));

                RETURN _result;
        END IF;
   END IF;

   RETURN 'Err';

END;

Function: public.formatplonumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPlanordid ALIAS FOR $1;
  _result TEXT;

BEGIN

  SELECT (TEXT(planord_number) || '-' || TEXT(planord_subnumber)) INTO _result
  FROM planord
  WHERE (planord_id=pPlanordid);

  RETURN _result;

END;

Function: public.formatprcnt(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT formatNumeric($1 * 100, 'percent')  AS result

Function: public.formatprice(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT formatNumeric($1, 'salesprice') AS result;

Function: public.formatpurchprice(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'purchprice');
END;

Function: public.formatqty(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'qty');
END;

Function: public.formatqtyper(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'qtyper');
END;

Function: public.formatratio(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT formatNumeric($1, 'uomratio');

Function: public.formatrevnumber(text, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pRevType 	ALIAS FOR $1;
  pRevId 	ALIAS FOR $2;
  _revision 	TEXT;

BEGIN
  --See if revision control turned on (Postbooks will not ever have this)
  IF (fetchmetricbool('RevControl')) THEN
    SELECT rev_number INTO _revision
    FROM rev
    WHERE ((rev_target_type=pRevType)
    AND (rev_id=pRevId));
  END IF;

  RETURN COALESCE(_revision,'');

END;

Function: public.formatsalesprice(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'salesprice');
END;

Function: public.formatscrap(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT formatNumeric(($1 * 100), 'percent') AS result

Function: public.formatshipmentnumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pshipheadid    ALIAS FOR $1;
BEGIN
  RETURN ( SELECT COALESCE(shiphead_number::TEXT, '')
           FROM shiphead
           WHERE (shiphead_id=pshipheadid) );
END;

Function: public.formatsobarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138SOXX' ||
           LENGTH(TEXT(cohead_number)) || TEXT(cohead_number) ) INTO _barcode
  FROM cohead
  WHERE (cohead_id=pSoheadid);

  RETURN _barcode;

END;

Function: public.formatsoitembarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138SOLI' ||
           LENGTH(TEXT(cohead_number)) || LENGTH(formatsolinenumber(coitem_id)) ||
           TEXT(cohead_number) || formatsolinenumber(coitem_id) ) INTO _barcode
  FROM cohead, coitem
  WHERE ( (coitem_cohead_id=cohead_id)
   AND (coitem_id=pSoitemid) );

  RETURN _barcode;

END;

Function: public.formatsoitemnumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  targetSoitemid ALIAS FOR $1;
BEGIN
  RETURN ( SELECT (cohead_number::TEXT || '-' || formatsolinenumber(coitem_id))
           FROM cohead, coitem
           WHERE ((coitem_cohead_id=cohead_id)
            AND (coitem_id=targetSoitemid)) );
END;

Function: public.formatsolinenumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemid ALIAS FOR $1;
  _r RECORD;

BEGIN

  SELECT coitem_linenumber, coitem_subnumber
    INTO _r
    FROM coitem
   WHERE(coitem_id=pSoitemid);

  IF(NOT FOUND) THEN
    RETURN NULL;
  END IF;

  IF(COALESCE(_r.coitem_subnumber, 0) > 0) THEN
    RETURN _r.coitem_linenumber || '.' || _r.coitem_subnumber;
  END IF;

  RETURN _r.coitem_linenumber; 
END;

Function: public.formatsonumber(integer)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT COALESCE((SELECT (text(cohead_number) || '-' || formatSoLineNumber(coitem_id))
                   FROM coitem JOIN cohead ON (coitem_cohead_id=cohead_id)
                  WHERE (coitem_id=($1))),'DELETED');

Function: public.formattime(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT LTRIM(TO_CHAR(COALESCE($1, 0), '999999990.0'));

Function: public.formattime(timestamp with time zone)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT TO_CHAR($1, ( SELECT locale_timeformat
                       FROM locale, usr
                       WHERE ((usr_locale_id=locale_id)
                        AND (usr_username=getEffectiveXtUser())) ) ) AS result

Function: public.formatuomratio(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN formatNumeric($1, 'uomratio');
END;

Function: public.formatuserbarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUserid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT formatUserBarcode(usr_username) INTO _barcode
    FROM usr
   WHERE(usr_id=pUserid);

  RETURN _barcode;

END;

Function: public.formatuserbarcode(text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  _barcode := ( E'\138USER' || LENGTH(pUsername)::TEXT || pUsername );

  RETURN _barcode;

END;

Function: public.formatweight(numeric)

Returns: text

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT formatNumeric($1, 'weight') AS result

Function: public.formatwobarcode(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  _barcode TEXT;
BEGIN

  SELECT ( E'\138WOXX' ||
           LENGTH(wo_number::TEXT) || LENGTH(wo_subnumber::TEXT) ||
           wo_number::TEXT || wo_subnumber::TEXT ) INTO _barcode
  FROM wo
  WHERE (wo_id=pWoid);

  RETURN _barcode;

END;

Function: public.formatwonumber(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;

BEGIN

  RETURN ( SELECT (wo_number::TEXT || '-' || wo_subnumber::TEXT)
           FROM wo
           WHERE (wo_id=pWoid) );

END;

Function: public.formatwooperseq(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWooperId  ALIAS FOR $1;
  _result    TEXT;

BEGIN

  IF pWooperId = -1 THEN
    RETURN '';
  ELSE
    SELECT wooper_seqnumber INTO _result
    FROM xtmfg.wooper
    WHERE (wooper_id=pWooperId);
  END IF;

  RETURN _result;
END;

Function: public.forwardupdateaccount(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntid ALIAS FOR $1;
  _r RECORD;
  _trialbalid INTEGER;

BEGIN
  SELECT trialbal_id, trialbal_dirty,
         CASE WHEN (trialbal_dirty) THEN 0
              ELSE 1
         END AS dirty_seq INTO _r
    FROM trialbal, period
   WHERE ((trialbal_period_id=period_id)
     AND  (trialbal_accnt_id=pAccntid))
   ORDER BY dirty_seq, period_start
   LIMIT 1;
  IF (FOUND) THEN
    IF (_r.trialbal_dirty) THEN
      RETURN forwardUpdateTrialBalance(_r.trialbal_id);
    ELSE
      RETURN _r.trialbal_id;
    END IF;
  ELSE
      _trialbalid := nextval('trialbal_trialbal_id_seq');
      
      INSERT INTO trialbal
      ( trialbal_id,
        trialbal_period_id, trialbal_accnt_id,
        trialbal_beginning, trialbal_ending,
        trialbal_debits, trialbal_credits, trialbal_dirty )
      SELECT
        _trialbalid,
        period_id, pAccntid,
        0, 0,
        0, 0, FALSE
      FROM period
      ORDER BY period_start LIMIT 1;

      RETURN forwardUpdateTrialBalance(_trialbalid);
  END IF;

  RETURN -1;
END;

Function: public.forwardupdateinvbalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvbalid ALIAS FOR $1;
  _p RECORD;
  _r RECORD;
  _qohEnding NUMERIC;
  _valueEnding NUMERIC;
  _nnEnding NUMERIC;
  _nnvalEnding NUMERIC;

BEGIN

  SELECT invbal_itemsite_id, 
         invbal_qoh_ending,
         invbal_value_ending,
         invbal_nn_ending,
         invbal_nnval_ending,
         period_end INTO _p
  FROM invbal
    JOIN period ON (invbal_period_id=period_id)
    JOIN itemsite ON (invbal_itemsite_id=itemsite_id)
  WHERE (invbal_id=pInvbalid);

  _qohEnding = _p.invbal_qoh_ending;
  _valueEnding = _p.invbal_value_ending;
  _nnEnding = _p.invbal_nn_ending;
  _nnvalEnding = _p.invbal_nnval_ending;

--  Find all of the subsequent periods and their inventory balance, if they exist
  FOR _r IN SELECT period_id, period_end,
                   invbal_id, 
                   invbal_qty_in, invbal_qty_out,
                   invbal_value_in, invbal_value_out,
                   invbal_nn_in, invbal_nn_out,
                   invbal_nnval_in, invbal_nnval_out
            FROM period 
              LEFT OUTER JOIN invbal
                 ON ( (invbal_period_id=period_id) AND (invbal_itemsite_id=_p.invbal_itemsite_id) )
            WHERE (period_start > _p.period_end)
            ORDER BY period_start LOOP

    IF (_r.invbal_id IS NULL) THEN

      INSERT INTO invbal
      ( invbal_period_id, invbal_itemsite_id,
        invbal_qoh_beginning, invbal_qoh_ending,
        invbal_qty_in, invbal_qty_out,
        invbal_value_beginning, invbal_value_ending,
        invbal_value_in, invbal_value_out, 
        invbal_nn_beginning, invbal_nn_ending,
        invbal_nn_in, invbal_nn_out,
        invbal_nnval_beginning, invbal_nnval_ending,
        invbal_nnval_in, invbal_nnval_out, 
        invbal_dirty )
      VALUES
      ( _r.period_id, _p.invbal_itemsite_id,
        _qohEnding, _qohEnding,
        0, 0, 
        _valueEnding, _valueEnding,
        0, 0,
        _nnEnding, _nnEnding,
        0, 0, 
        _nnvalEnding, _nnvalEnding,
        0, 0,
        FALSE );
    ELSE
      UPDATE invbal
      SET invbal_qoh_beginning = (_qohEnding),
          invbal_qoh_ending = (_qohEnding + _r.invbal_qty_in - _r.invbal_qty_out),
          invbal_value_beginning = (_valueEnding),
          invbal_value_ending = (_valueEnding + _r.invbal_value_in - _r.invbal_value_out),
          invbal_nn_beginning = (_nnEnding),
          invbal_nn_ending = (_nnEnding + _r.invbal_nn_in - _r.invbal_nn_out),
          invbal_nnval_beginning = (_nnvalEnding),
          invbal_nnval_ending = (_nnvalEnding + _r.invbal_nnval_in - _r.invbal_nnval_out),
          invbal_dirty = FALSE
      WHERE (invbal_id=_r.invbal_id);

      _qohEnding = (_qohEnding + _r.invbal_qty_in - _r.invbal_qty_out);
      _valueEnding = (_valueEnding + _r.invbal_value_in - _r.invbal_value_out);
      _nnEnding = (_nnEnding + _r.invbal_nn_in - _r.invbal_nn_out);
      _nnvalEnding = (_nnvalEnding + _r.invbal_nnval_in - _r.invbal_nnval_out);
    END IF;
  END LOOP;

  UPDATE invbal
  SET invbal_dirty = false
  WHERE (invbal_id=pInvbalid);

  RETURN pInvbalid;

END;

Function: public.forwardupdateitemsite(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  _r RECORD;
  _invbalid INTEGER;

BEGIN
  SELECT invbal_id INTO _r
  FROM invbal
      JOIN period ON (invbal_period_id=period_id)
  WHERE (invbal_itemsite_id=pItemsiteid)
  ORDER BY period_start
  LIMIT 1;

  IF (FOUND) THEN
    RETURN forwardUpdateInvbalance(_r.invbal_id);
  ELSE
      _invbalid := nextval('invbal_invbal_id_seq');
      
      INSERT INTO invbal
      ( invbal_id,
        invbal_period_id, invbal_itemsite_id,
        invbal_qoh_beginning, invbal_qoh_ending,
        invbal_qty_in, invbal_qty_out,
        invbal_value_beginning, invbal_value_ending,
        invbal_value_in, invbal_value_out,
        invbal_nn_beginning, invbal_nn_ending,
        invbal_nn_in, invbal_nn_out,
        invbal_nnval_beginning, invbal_nnval_ending,
        invbal_nnval_in, invbal_nnval_out,
        invbal_dirty )
      SELECT
        _invbalid,
        period_id, pItemsiteid,
        0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0,
        false
      FROM period
      ORDER BY period_start LIMIT 1;

      RETURN forwardUpdateInvbalance(_invbalid);
  END IF;

  RETURN -1;
END;

Function: public.forwardupdatetrialbalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTrialbalid ALIAS FOR $1;
  _p RECORD;
  _r RECORD;
  _ending NUMERIC;
  _prevYear INTEGER;
  _currYear INTEGER;
  _prevYearClosed BOOLEAN;
  _currYearClosed BOOLEAN;
  _result INTEGER;

BEGIN

  SELECT trialbal_accnt_id, trialbal_ending,
         yearperiod_id, yearperiod_closed,
         period_end, accnt_type IN ('E', 'R') AS revexp INTO _p
  FROM trialbal, period, yearperiod, accnt
  WHERE ( (trialbal_period_id=period_id)
   AND (yearperiod_id=period_yearperiod_id)
   AND (trialbal_accnt_id=accnt_id)
   AND (trialbal_id=pTrialbalid) );

  _ending = _p.trialbal_ending;

  SELECT yearperiod_id, yearperiod_closed INTO _prevYear, _prevYearClosed
    FROM yearperiod
   WHERE (_p.period_end BETWEEN yearperiod_start AND yearperiod_end);
  IF (NOT FOUND) THEN
    _prevYear := -1;
    _prevYearClosed := false;
  END IF;

--  Find all of the subsequent periods and their trialbal, if they exist
  FOR _r IN SELECT period_id, period_end,
                   trialbal_id, trialbal_debits, trialbal_credits,
                   trialbal_yearend
            FROM period LEFT OUTER JOIN trialbal
                 ON ( (trialbal_period_id=period_id) AND (trialbal_accnt_id=_p.trialbal_accnt_id) )
            WHERE (period_start > _p.period_end)
            ORDER BY period_start LOOP

    SELECT yearperiod_id, yearperiod_closed INTO _currYear, _currYearClosed
      FROM yearperiod
     WHERE (_r.period_end BETWEEN yearperiod_start AND yearperiod_end);
    IF (NOT FOUND) THEN
      _currYear := -1;
      _currYearClosed := false;
    END IF;

    IF (_p.revexp AND _currYear != _prevYear) THEN
      _ending := 0;
      IF (_prevYearClosed) THEN
        SELECT updateRetainedEarnings(_prevYear) INTO _result;
        IF (_result < 0) THEN
          RETURN _result;
        END IF;
      END IF;
    END IF;

    _prevYear := _currYear;
    _prevYearClosed := _currYearClosed;

    IF (_r.trialbal_id IS NULL) THEN
      -- SELECT SUM(gltrans_amount) INTO _glAmount
       -- FROM gltrans
       -- WHERE ( (gltrans_date BETWEEN _r.period_start and _r.period_end )
         -- AND   (gltrans_accnt_id=_p.trialbal_accnt_id)
         -- AND   (gltrans_posted) );
        -- and change 2nd and 3rd VALUES line of INSERT to read
        --      _ending, _ending + _glAmount,
        --      noneg(0 - _glAmount), noneg(_glAmount), FALSE );

      INSERT INTO trialbal
      ( trialbal_period_id, trialbal_accnt_id,
        trialbal_beginning, trialbal_ending,
        trialbal_debits, trialbal_credits, trialbal_dirty )
      VALUES
      ( _r.period_id, _p.trialbal_accnt_id,
        _ending, _ending,
        0, 0, FALSE );
    ELSE
      UPDATE trialbal
      SET trialbal_beginning = (_ending + trialbal_yearend),
          trialbal_ending = (_ending + trialbal_yearend - _r.trialbal_debits + _r.trialbal_credits),
          trialbal_dirty = FALSE
      WHERE (trialbal_id=_r.trialbal_id);

      _ending = (_ending + _r.trialbal_yearend - _r.trialbal_debits + _r.trialbal_credits);
    END IF;
  END LOOP;

  UPDATE trialbal
  SET trialbal_dirty = FALSE
  WHERE (trialbal_id=pTrialbalid);

  RETURN pTrialbalid;

END;

Function: public.freezeaccountingperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;

BEGIN

--  Check to make use that the period is not already frozen
  IF ( ( SELECT period_freeze
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -2;
  END IF;

--  Set the period_freeze flag
  UPDATE period
  SET period_freeze=TRUE
  WHERE (period_id=pPeriodid);

  RETURN pPeriodid;

END;

Function: public.freightdetail(text, integer, integer, integer, date, text, integer)

Returns: SET OF freightdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrderType ALIAS FOR $1;
  pOrderId ALIAS FOR $2;
  pCustId ALIAS FOR $3;
  pShiptoId ALIAS FOR $4;
  pOrderDate ALIAS FOR $5;
  pShipVia ALIAS FOR $6;
  pCurrId ALIAS FOR $7;

  _row freightData%ROWTYPE;
  _order RECORD;
  _weights RECORD;
  _includepkgweight BOOLEAN := FALSE;
  _qry TEXT;
  _debug BOOLEAN := FALSE;

BEGIN
  IF (_debug) THEN
    RAISE NOTICE 'pOrderType = %', pOrderType;
    RAISE NOTICE 'pOrderId = %', pOrderId;
    RAISE NOTICE 'pCustId = %', pCustId;
    RAISE NOTICE 'pShiptoId = %', pShiptoId;
    RAISE NOTICE 'pOrderDate = %', pOrderDate;
    RAISE NOTICE 'pShipVia = %', pShipVia;
    RAISE NOTICE 'pCurrId = %', pCurrId;
  END IF;

  SELECT fetchMetricBool('IncludePackageWeight') INTO _includepkgweight;

  --Get the order header information need to match
  --against price schedules
  IF (pOrderType = 'SO') THEN
    SELECT
      cust_id AS cust_id,
      custtype_id,
      custtype_code,
      COALESCE(shipto_id, -1) AS shipto_id,
      COALESCE(shipto_num, '') AS shipto_num,
      COALESCE(pOrderDate, cohead_orderdate) AS orderdate,
      COALESCE(pShipVia, cohead_shipvia) AS shipvia,
      shipto_shipzone_id AS shipzone_id,
      COALESCE(pCurrId, cohead_curr_id) AS curr_id,
      currConcat(COALESCE(pCurrId, cohead_curr_id)) AS currAbbr
    INTO _order
      FROM cohead
      JOIN custinfo ON (cust_id=COALESCE(pCustId, cohead_cust_id))
      JOIN custtype ON (custtype_id=cust_custtype_id)
      LEFT OUTER JOIN shiptoinfo ON (shipto_id=COALESCE(pShiptoId, cohead_shipto_id))
    WHERE (cohead_id=pOrderId);

  ELSIF (pOrderType = 'QU') THEN
    SELECT
      quhead_cust_id AS cust_id,
      custtype_id,
      custtype_code,
      COALESCE(shipto_id, -1) AS shipto_id,
      COALESCE(shipto_num, '') AS shipto_num,
      quhead_quotedate AS orderdate,
      quhead_shipvia AS shipvia,
      shipto_shipzone_id AS shipzone_id,
      quhead_curr_id AS curr_id,
      currConcat(quhead_curr_id) AS currAbbr
    INTO _order
      FROM quhead
      JOIN custinfo ON (cust_id=quhead_cust_id)
      JOIN custtype ON (custtype_id=cust_custtype_id)
      LEFT OUTER JOIN shiptoinfo ON (shipto_id=quhead_shipto_id)
    WHERE (quhead_id=pOrderId);

  ELSIF (pOrderType = 'RA') THEN
    SELECT
      cust_id AS cust_id,
      custtype_id,
      custtype_code,
      COALESCE(shipto_id, -1) AS shipto_id,
      COALESCE(shipto_num, '') AS shipto_num,
      COALESCE(pOrderDate, rahead_authdate) AS orderdate,
      ''::text AS shipvia,
      shipto_shipzone_id AS shipzone_id,
      COALESCE(pCurrId, rahead_curr_id) AS curr_id,
      currConcat(COALESCE(pCurrId, rahead_curr_id)) AS currAbbr
    INTO _order
      FROM rahead
      JOIN custinfo ON (cust_id=COALESCE(pCustId, rahead_cust_id))
      JOIN custtype ON (custtype_id=cust_custtype_id)
      LEFT OUTER JOIN shiptoinfo ON (shipto_id=COALESCE(pShiptoId, rahead_shipto_id))
    WHERE (rahead_id=pOrderId);

  ELSE
    RAISE EXCEPTION 'Invalid order type.';
  END IF;

  IF (_debug) THEN
    RAISE NOTICE 'cust_id = %', _order.cust_id;
    RAISE NOTICE 'custtype_id = %', _order.custtype_id;
    RAISE NOTICE 'shipto_id = %', _order.shipto_id;
    RAISE NOTICE 'shipto_num = %', _order.shipto_num;
    RAISE NOTICE 'orderdate = %', _order.orderdate;
    RAISE NOTICE 'shipvia = %', _order.shipvia;
    RAISE NOTICE 'shipzone_id = %', _order.shipzone_id;
    RAISE NOTICE 'curr_id = %', _order.curr_id;
    RAISE NOTICE 'currAbbr = %', _order.currAbbr;
  END IF;

  --Get a list of aggregated weights from sites and
  --freight classes used on order lines

  IF (_includePkgWeight) THEN
    _qry := 'SELECT SUM(orderitem_qty_ordered * (item_prodweight + item_packweight)) AS weight, ';
  ELSE
    _qry := 'SELECT SUM(orderitem_qty_ordered * item_prodweight) AS weight, ';
  END IF;

  _qry := _qry || 'itemsite_warehous_id, COALESCE(item_freightclass_id, -1) AS item_freightclass_id
    FROM orderitem
    JOIN itemsite ON (itemsite_id=orderitem_itemsite_id)
    JOIN item ON (item_id=itemsite_item_id) ';

  IF (pOrderType = 'RA') THEN
    _qry := _qry || 'JOIN raitem ON ((orderitem_id=raitem_id)
    AND (raitem_disposition IN (''C'',''R'',''P''))) ';
  END IF;

  _qry := _qry || '
    WHERE ( (orderitem_orderhead_type=' || quote_literal(pOrderType) || ')
      AND (orderitem_orderhead_id=' || quote_literal(pOrderId) || ')
      AND (orderitem_status <> ''X'') )
    GROUP BY itemsite_warehous_id, item_freightclass_id;';

  FOR _weights IN
    EXECUTE _qry LOOP

    _row := calculateFreightDetail(
      _order.cust_id, --pCustId
      _order.custtype_id, --pCustTypeId
      _order.custtype_code, --pCustTypeCode
      _order.shipto_id, --pShiptoId
      _order.shipzone_id, --pShipZoneId
      _order.shipto_num, --pShiptoNum
      _order.orderdate, --pOrderDate
      _order.shipvia, --pShipVia
      _order.curr_id, --pCurrId
      _order.currAbbr, --pCurrAbbr
      _weights.itemsite_warehous_id, --pItemSiteWhsId
      _weights.item_freightclass_id, --pItemFreightclassId
      _weights.weight --pWeight
      );

    RETURN NEXT _row;

  END LOOP;
  RETURN;
END;

Function: public.freightdetailquote(integer, text, integer, text, date, text, text, text[])

Returns: SET OF freightdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustId ALIAS FOR $1;
  pCustNumber ALIAS FOR $2;
  pShiptoId ALIAS FOR $3;
  pShiptoNum ALIAS FOR $4;
  pOrderDate ALIAS FOR $5;
  pShipVia ALIAS FOR $6;
  pItemArrayType ALIAS FOR $7;
  pItemQty ALIAS FOR $8;
    -- Array item_id format = ARRAY[['300','3'],['310','50']]
    -- Array item_number format = ARRAY[['YTRUCK1','3'],['RTRUCK1','50']]
    -- Array itemsite_id format = ARRAY[['293','3'],['302','50']]

  _cust RECORD;
  _shipto RECORD;
  _curr RECORD;
  _includepkgweight BOOLEAN := FALSE;
  _order_date DATE;
  _ship_via TEXT;
  _item_num RECORD;
  _item_id RECORD;
  _weights RECORD;
  _row freightData%ROWTYPE;
  _debug BOOLEAN := FALSE;

BEGIN
-- Parameters are setup to allow this function to be called multiple ways.
-- Check parameters and lookup what is NULL.

  -- Check pCustId and pCustNumber.
  IF (pCustId IS NULL AND (pCustNumber IS NULL OR pCustNumber = '')) THEN
    RAISE EXCEPTION 'You must specify a Customer ID or Number to get a freight quote.';
  ELSIF (pCustId IS NULL AND pCustNumber IS NOT NULL) THEN
    -- Get customer info using pCustNumber.
    SELECT
      cust_id,
      cust_number,
      custtype_id,
      custtype_code,
      cust_curr_id,
      cust_shipvia
    INTO _cust
    FROM custinfo
    LEFT JOIN custtype ON cust_custtype_id = custtype_id
    WHERE 1=1
      AND cust_number = pCustNumber;
  ELSE
    -- Get customer info using pCustId.
    SELECT
      cust_id,
      cust_number,
      custtype_id,
      custtype_code,
      cust_curr_id,
      cust_shipvia
    INTO _cust
    FROM custinfo
    LEFT JOIN custtype ON cust_custtype_id = custtype_id
    WHERE 1=1
      AND cust_id = pCustId;
  END IF;

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'Invalid Customer specified when trying to get a freight quote.';
  END IF;

  -- Check pShiptoId and pShiptoNum.
  IF (pShiptoId IS NULL AND (pShiptoNum IS NULL OR pShiptoNum = '')) THEN
    -- Get Customer's default shipto.
    SELECT
      shipto_id,
      shipto_name,
      shipto_shipzone_id,
      shipto_shipvia,
      shipto_num
    INTO _shipto
    FROM shiptoinfo
    WHERE 1=1
      AND shipto_cust_id = _cust.cust_id
      AND shipto_default;
  ELSIF (pShiptoId IS NULL AND pShiptoNum IS NOT NULL) THEN
    -- Get shipto info using pShiptoNum.
    SELECT
      shipto_id,
      shipto_name,
      shipto_shipzone_id,
      shipto_shipvia,
      shipto_num
    INTO _shipto
    FROM shiptoinfo
    WHERE 1=1
      AND shipto_cust_id = _cust.cust_id
      AND shipto_num = pShiptoNum;
  ELSE
    -- Get shipto info using pShiptoId.
    SELECT
      shipto_id,
      shipto_name,
      shipto_shipzone_id,
      shipto_shipvia,
      shipto_num
    INTO _shipto
    FROM shiptoinfo
    WHERE 1=1
      AND shipto_cust_id = _cust.cust_id
      AND shipto_id = pShiptoId;
  END IF;

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'Invalid Ship-to specified when trying to get a freight quote.';
  END IF;

  -- Get curr info.
  SELECT
    curr_id,
    curr_abbr
  INTO _curr
  FROM curr_symbol
  WHERE 1=1
    AND curr_id = _cust.cust_curr_id;

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'Could not find currency when trying to get a freight quote.';
  END IF;

  -- Check pOrderDate.
  IF (pOrderDate IS NULL) THEN
    _order_date := CURRENT_DATE;
  ELSE
    _order_date := pOrderDate;
  END IF;

  -- Check pShipVia.
  IF (pShipVia IS NULL OR pShipVia = '') THEN
    IF (_shipto.shipto_shipvia IS NULL OR _shipto.shipto_shipvia = '') THEN
      _ship_via := _cust.cust_shipvia;
    ELSE
      _ship_via := _shipto.shipto_shipvia;
    END IF;
  ELSE
    _ship_via := pShipVia;
  END IF;

  -- Determine if package weight should be included in freight calculation.
  SELECT fetchMetricBool('IncludePackageWeight') INTO _includepkgweight;

  -- Check pItemQty.
  IF (pItemQty IS NULL OR array_upper(pItemQty,1) IS NULL) THEN
    -- Item Array is NULL.
    RAISE EXCEPTION 'You must specify an Item ID, Item Number or Itemsite ID to get a freight quote.';
  ELSIF (pItemArrayType = 'item_number' AND (array_upper(pItemQty,1) > 0)) THEN
    -- Using item_number.
    FOR _weights IN
      -- Get a list of aggregated weights from sites and freight classes for items.
      SELECT
        CASE WHEN _includepkgweight THEN
          SUM(qty * (item_prodweight + item_packweight))
        ELSE
          SUM(qty * (item_prodweight))
        END AS weight,
        itemsite_warehous_id,
        COALESCE(item_freightclass_id, -1) AS item_freightclass_id
      FROM
        -- Create item_number -> qty record from array.
        (SELECT
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][1])) AS item_number,
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][2:array_ndims(pItemQty)]))::numeric AS qty
        ) AS itemnum_qty
        JOIN item USING (item_number)
        JOIN itemsite ON item_id=itemsite_item_id
      WHERE 1=1
        AND itemsite_warehous_id = fetchprefwarehousid()
      GROUP BY
        itemsite_warehous_id,
        item_freightclass_id
    LOOP
      -- Calculate the freight detail for these item weights.
      _row := calculateFreightDetail(
        _cust.cust_id, --pCustId
        _cust.custtype_id, --pCustTypeId
        _cust.custtype_code, --pCustTypeCode
        _shipto.shipto_id, --pShiptoId
        _shipto.shipto_shipzone_id, --pShipZoneId
        _shipto.shipto_num, --pShiptoNum
        _order_date, --pOrderDate
        _ship_via, --pShipVia
        _curr.curr_id, --pCurrId
        _curr.curr_abbr, --pCurrAbbr
        _weights.itemsite_warehous_id, --pItemSiteWhsId
        _weights.item_freightclass_id, --pItemFreightclassId
        _weights.weight --pWeight
        );

      RETURN NEXT _row;
    END LOOP;

  ELSIF (pItemArrayType = 'item_id' AND (array_upper(pItemQty,1) > 0)) THEN
    -- Using item_id.
    FOR _weights IN
      -- Get a list of aggregated weights from sites and freight classes for items.
      SELECT
        CASE WHEN _includepkgweight THEN
          SUM(qty * (item_prodweight + item_packweight))
        ELSE
          SUM(qty * (item_prodweight))
        END AS weight,
        itemsite_warehous_id,
        COALESCE(item_freightclass_id, -1) AS item_freightclass_id
      FROM
        -- Create item_id -> qty record from array.
        (SELECT
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][1]))::integer AS item_id,
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][2:array_ndims(pItemQty)]))::numeric AS qty
        ) AS itemid_qty
        JOIN item USING (item_id)
        JOIN itemsite ON item_id=itemsite_item_id
      WHERE 1=1
        AND itemsite_warehous_id = fetchprefwarehousid()
      GROUP BY
        itemsite_warehous_id,
        item_freightclass_id
    LOOP
      -- Calculate the freight detail for these item weights.
      _row := calculateFreightDetail(
        _cust.cust_id, --pCustId
        _cust.custtype_id, --pCustTypeId
        _cust.custtype_code, --pCustTypeCode
        _shipto.shipto_id, --pShiptoId
        _shipto.shipto_shipzone_id, --pShipZoneId
        _shipto.shipto_num, --pShiptoNum
        _order_date, --pOrderDate
        _ship_via, --pShipVia
        _curr.curr_id, --pCurrId
        _curr.curr_abbr, --pCurrAbbr
        _weights.itemsite_warehous_id, --pItemSiteWhsId
        _weights.item_freightclass_id, --pItemFreightclassId
        _weights.weight --pWeight
        );

      RETURN NEXT _row;
    END LOOP;
  ELSIF (pItemArrayType = 'itemsite_id' AND (array_upper(pItemQty,1) > 0)) THEN
    -- Using itemsite_id.
    FOR _weights IN
      -- Get a list of aggregated weights from sites and freight classes for items.
      SELECT
        CASE WHEN _includepkgweight THEN
          SUM(qty * (item_prodweight + item_packweight))
        ELSE
          SUM(qty * (item_prodweight))
        END AS weight,
        itemsite_warehous_id,
        COALESCE(item_freightclass_id, -1) AS item_freightclass_id
      FROM
        -- Create itemsite_id -> qty record from array.
        (SELECT
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][1]))::integer AS itemsite_id,
          unnest((SELECT pItemQty[1:array_upper(pItemQty,1)][2:array_ndims(pItemQty)]))::numeric AS qty
        ) AS itemsiteid_qty
        JOIN itemsite USING (itemsite_id)
        JOIN item ON item_id=itemsite_item_id
      WHERE 1=1
      GROUP BY
        itemsite_warehous_id,
        item_freightclass_id
    LOOP
      -- Calculate the freight detail for these item weights.
      _row := calculateFreightDetail(
        _cust.cust_id, --pCustId
        _cust.custtype_id, --pCustTypeId
        _cust.custtype_code, --pCustTypeCode
        _shipto.shipto_id, --pShiptoId
        _shipto.shipto_shipzone_id, --pShipZoneId
        _shipto.shipto_num, --pShiptoNum
        _order_date, --pOrderDate
        _ship_via, --pShipVia
        _curr.curr_id, --pCurrId
        _curr.curr_abbr, --pCurrAbbr
        _weights.itemsite_warehous_id, --pItemSiteWhsId
        _weights.item_freightclass_id, --pItemFreightclassId
        _weights.weight --pWeight
        );

      RETURN NEXT _row;
    END LOOP;
  ELSE -- The item array provided is invalid.
    RAISE EXCEPTION 'The Item/Itemsite array provided when trying to get a freight quote is invalid.';
  END IF;

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'Error trying to aggregated weights when getting a freight quote.';
  END IF;

  -- Print debug.
  IF (_debug) THEN
    RAISE NOTICE 'pCustId = %', _cust.cust_id;
    RAISE NOTICE 'pCustTypeId = %', _cust.custtype_id;
    RAISE NOTICE 'pCustTypeCode = %', _cust.custtype_code;
    RAISE NOTICE 'pShiptoId = %', _shipto.shipto_id;
    RAISE NOTICE 'pShipZoneId = %', _shipto.shipto_shipzone_id;
    RAISE NOTICE 'pShiptoNum = %', _shipto.shipto_num;
    RAISE NOTICE 'pOrderDate = %', _order_date;
    RAISE NOTICE 'pShipVia = %', _ship_via;
    RAISE NOTICE 'pCurrId = %', _curr.curr_id;
    RAISE NOTICE 'pCurrAbbr = %', _curr.curr_abbr;
  END IF;

  RETURN;
END;

Function: public.freightforrecv(text, integer, boolean)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  porderitemid	ALIAS FOR $2;
  pposted	ALIAS FOR $3;
  _freight	NUMERIC;

BEGIN
  IF (pordertype = 'TO' AND NOT fetchMetricBool('MultiWhs')) THEN
    RETURN 0;
  ELSIF (pordertype = 'RA' AND NOT fetchMetricBool('EnableReturnAuth')) THEN
    RETURN 0;
  END IF;

  SELECT SUM(COALESCE(recv_freight, 0)) INTO _freight
  FROM recv
  WHERE ((recv_orderitem_id=porderitemid)
    AND  (recv_posted = pposted)
    AND  (recv_order_type=pordertype));

  RETURN COALESCE(_freight, 0.0);

END;

Function: public.gen_salt(text)

Returns: text

Language: C

pg_gen_salt

Function: public.gen_salt(text, integer)

Returns: text

Language: C

pg_gen_salt_rounds

Function: public.getactiverevid(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetType ALIAS FOR $1;
  pTargetid ALIAS FOR $2;
  _revid INTEGER;

BEGIN
  --See if revcontrol turned on
  IF (fetchmetricbool('RevControl')) THEN

    IF (pTargetType='BOM') THEN
      SELECT rev_id INTO _revid
      FROM rev
      WHERE ((rev_target_type='BOM')
      AND (rev_target_id=pTargetid)
      AND (rev_status='A'));
      IF (NOT FOUND) THEN
        _revid:=-1;
      END IF;

      ELSE IF (pTargetType='BOO') THEN
      SELECT rev_id INTO _revid
      FROM rev
      WHERE ((rev_target_type='BOO')
      AND (rev_target_id=pTargetid)
      AND (rev_status='A'));
      IF (NOT FOUND) THEN
        _revid:=-1;
      END IF;

      ELSE
        RAISE EXCEPTION 'Invalid Revision Type';
      END IF;
    END IF;

  ELSE
    _revid:=-1;
  END IF;

  RETURN _revid;

END;

Function: public.getaddrid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAddressNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pAddressNumber IS NULL OR pAddressNumber = '') THEN
    RETURN NULL;
  END IF;

  SELECT addr_id INTO _returnVal
  FROM addr
  WHERE (addr_number=pAddressNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Address Number % not found.', pAddressNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getadjustmenttaxtypeid()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _taxtypeid INTEGER;
BEGIN
  SELECT taxtype_id
    INTO _taxtypeid
  FROM taxtype
  WHERE (taxtype_name='Adjustment');

  RETURN _taxtypeid;
END;

Function: public.getaropenid(text, bpchar, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustNumber ALIAS FOR $1;
  pDocType ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  _returnVal INTEGER;
BEGIN
  IF ((pCustNumber IS NULL) OR (pDocType IS NULL) OR (pDocNumber IS NULL)) THEN
	RETURN NULL;
  END IF;

  SELECT aropen_id INTO _returnVal
  FROM aropen
  WHERE ((aropen_cust_id=getCustId(pCustNumber,true))
    AND  (UPPER(aropen_doctype)=UPPER(pDocType))
    AND  (UPPER(aropen_docnumber)=UPPER(pDocNumber)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'AR Open Item % not found.', pDocNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getbankaccntid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankAccntName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pBankAccntName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT bankaccnt_id INTO _returnVal
  FROM bankaccnt
  WHERE (UPPER(bankaccnt_name)=UPPER(pBankAccntName));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Bank Account % not found.', pBankAccntName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getbomitemid(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemNumber ALIAS FOR $1;
  pRevision ALIAS FOR $2;
  pSeqNumber ALIAS FOR $3;
  _returnVal INTEGER;
  
BEGIN
  IF ((pItemNumber IS NULL) OR (pSeqNumber IS NULL) OR (pItemNumber = '') OR (pSeqNumber = '') ) THEN
    RETURN NULL;
  END IF;

  SELECT bomitem_id INTO _returnVal
  FROM bomitem(getItemId(pItemNumber),COALESCE(getRevId('BOM',pItemNumber,pRevision)))
  WHERE (bomitem_seqnumber=pSeqNumber);
    
  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Sequence % on Bill of Material % Revision % not found.', pSeqNumber, pItemNumber, pRevision;
  END IF;

  RETURN _returnVal;
END;

Function: public.getbooitemseqid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemNumber ALIAS FOR $1;
  pSeqNumber ALIAS FOR $2;
  _revid INTEGER;
  _returnVal INTEGER;
  
BEGIN
  IF ((pItemNumber IS NULL) OR (pSeqNumber IS NULL)) THEN
    RETURN NULL;
  END IF;

  IF (NOT fetchMetricBool('Routings')) THEN
    RETURN -1;
  ELSE
    SELECT booitem_seq_id INTO _returnVal
    FROM booitem(getItemId(pItemNumber))
    WHERE (booitem_seqnumber=CAST(pSeqNumber AS integer));
  END IF;
    
  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Boo Sequence % for Item % not found.', pSeqNumber, pItemNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getbudgheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBudghead ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pBudghead IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT budghead_id INTO _returnVal
  FROM budghead
  WHERE (budghead_name=(pBudghead));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Budget % not found.', pBudghead;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcashrcptid(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustNumber ALIAS FOR $1;
  pFundsType ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  _returnVal INTEGER;
BEGIN
  IF ((pCustNumber IS NULL) OR (pFundsType IS NULL) OR (pDocNumber IS NULL)) THEN
	RETURN NULL;
  END IF;

  SELECT cashrcpt_id INTO _returnVal
  FROM cashrcpt
  WHERE ((cashrcpt_cust_id=getCustId(pCustNumber,true))
    AND  (UPPER(cashrcpt_fundstype)=UPPER(pFundsType))
    AND  (UPPER(cashrcpt_docnumber)=UPPER(pDocNumber)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Cash Receipt % not found.', pDocNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcharid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pChar ALIAS FOR $1;
  pType ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(pChar, '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT char_id INTO _returnVal
  FROM char
  WHERE ((char_name=pChar)
  AND ((pType IN ('C','CT') AND char_customers)
    OR (pType IN ('I','SI','QI','W','PI','TI') AND char_items)
    OR (pType='CRMACCT' AND char_crmaccounts)
    OR (pType='ADDR' AND char_addresses)
    OR (pType='CNTCT' AND char_contacts)
    OR (pType='LS' AND char_lotserial)
    OR (pType='EMP' AND char_employees)
    OR (pType='INCDT' AND char_incidents)
    )) LIMIT 1;

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Characteristic % not found.', pChar;
  END IF;

  RETURN _returnVal;
END;

Function: public.getclasscodeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClassCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pClassCode IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT classcode_id INTO _returnVal
  FROM classcode
  WHERE (classcode_code=pClassCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Class Code % not found.', pClassCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcmheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCreditMemoNumber ALIAS FOR $1;
BEGIN
  RETURN getCmheadId(pCreditMemoNumber, NULL);
END;

Function: public.getcmheadid(text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCreditMemoNumber ALIAS FOR $1;
  pPosted ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (pCreditMemoNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT cmhead_id INTO _returnVal
  FROM cmhead
  WHERE (UPPER(cmhead_number)=UPPER(pCreditMemoNumber))
    AND ((pPosted IS NULL) OR (cmhead_posted=pPosted));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Credit Memo % not found.', pCreditMemoNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcmnttypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmntType ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pCmntType), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT cmnttype_id INTO _returnVal
  FROM cmnttype
  WHERE (cmnttype_name=pCmntType) LIMIT 1;

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Comment Type % not found.', pCmntType;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcntctid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pContactNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  SELECT getCntctId(pContactNumber,true) INTO _returnVal;

  RETURN _returnVal;
END;

Function: public.getcntctid(text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pContactNumber ALIAS FOR $1;
  pNotFoundErr ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pContactNumber), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT cntct_id INTO _returnVal
  FROM cntct
  WHERE (cntct_number=pContactNumber);

  IF (_returnVal IS NULL AND pNotFoundErr) THEN
    RAISE EXCEPTION 'Contact Number % not found.', pContactNumber;
  ELSIF (_returnVal IS NULL) THEN
    RETURN NULL;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcoheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesOrderNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSalesOrderNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT cohead_id INTO _returnVal
  FROM cohead
  WHERE (cohead_number=pSalesOrderNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Order % not found.', pSalesOrderNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcoitemid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesOrderNumber	ALIAS FOR $1;
  pLineNumber 	    	ALIAS FOR $2;
  _linenumber		INTEGER;
  _subnumber		INTEGER;
  _returnVal 		INTEGER;
BEGIN
  IF (pSalesOrderNumber IS NULL OR pLineNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  --Parse Line Number
  IF (position('.' in pLineNumber) > 0) THEN
    _linenumber	:= CAST(substring(pLineNumber from 1 for position('.' in pLineNumber)-1) AS INTEGER);
    _subnumber	:= CAST(substring(pLineNumber from position('.' in pLineNumber)+1 for length(pLineNumber)) AS INTEGER);
  ELSE
    _linenumber	:= CAST(pLineNumber AS INTEGER);
    _subnumber	:= 0;
  END IF;

  SELECT coitem_id INTO _returnVal
  FROM cohead, coitem
  WHERE ((cohead_number=pSalesOrderNumber)
  AND (coitem_cohead_id=cohead_id)
  AND (coitem_linenumber=_linenumber)
  AND (coitem_subnumber=_subnumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Order % not found.', pSalesOrderNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcostcatid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCostCat ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pCostCat IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT costcat_id INTO _returnVal
  FROM costcat
  WHERE (costcat_code=pCostCat);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Cost Category Code % not found.', pCostCat;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcostelemid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCostElemType ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pCostElemType IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT costelem_id INTO _returnVal
  FROM costelem
  WHERE (costelem_type=pCostElemType);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Cost Element % not found.', pCostElemType;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcrmacctid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAcctNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  
  IF (pAcctNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT crmacct_id INTO _returnVal
  FROM crmacct
  WHERE (UPPER(crmacct_number)=UPPER(pAcctNumber));
  
  IF (_returnVal IS NULL) THEN
      RAISE EXCEPTION 'CRM Account Number % not found.', pAcctNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcurrid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCurrName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pCurrName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT curr_id INTO _returnVal
  FROM curr_symbol
  WHERE (curr_abbr=pCurrName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Currency % not found.', pCurrName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcustid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  
  SELECT getCustId(pCustNumber,false) INTO _returnVal;

  RETURN _returnVal;
END;

Function: public.getcustid(text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustNumber ALIAS FOR $1;
  pInclProspects ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (pCustNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT cust_id INTO _returnVal
  FROM custinfo
  WHERE (cust_number=UPPER(pCustNumber));
  
  IF (_returnVal IS NULL) THEN
    IF (pInclProspects) THEN
      SELECT prospect_id INTO _returnVal
      FROM prospect
      WHERE (UPPER(prospect_number)=UPPER(pCustNumber));
      IF (_returnVal IS NULL) THEN
        RAISE EXCEPTION 'Neither Customer nor Prospect Number % found.', pCustNumber;
      END IF;
    ELSE
      RAISE EXCEPTION 'Customer Number % not found.', pCustNumber;
    END IF;
  END IF;

  RETURN _returnVal;
END;

Function: public.getcustnamefrominfo(text, text, text, text, text, boolean)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _email	TEXT	:= COALESCE(UPPER($1), '');
  _company	TEXT	:= COALESCE(UPPER($2), '');
  _first	TEXT	:= COALESCE(UPPER($3), '');
  _last		TEXT	:= COALESCE(UPPER($4), '');
  _fullname	TEXT	:= COALESCE(UPPER($5), '');
  _generate	BOOLEAN	:= COALESCE($6, FALSE);
  _counter	INTEGER;
  _custcount	INTEGER	:= 0;
  _custname	TEXT;
  _candidate	RECORD;
  _r		RECORD;
BEGIN
  IF (_email != '') THEN
    SELECT count(*), cust_name INTO _custcount, _custname
    FROM custinfo LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
    WHERE (UPPER(cntct_email)=_email)
    GROUP BY cust_name;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custname;
    END IF;
  END IF;

  IF (_company != '') THEN
    SELECT count(*), cust_name INTO _custcount, _custname
    FROM custinfo
    WHERE (UPPER(cust_name)=_company)
    GROUP BY cust_name;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custname;
    END IF;
  END IF;

  IF (_fullname = '' AND (_first != '' OR _last != '')) THEN
    _fullname := TRIM(_first || ' ' || _last);
  END IF;

  IF (_custcount <= 0 AND _fullname != '') THEN
    SELECT count(*), cust_name INTO _custcount, _custname
    FROM custinfo
    WHERE (UPPER(cust_name)=_fullname)
    GROUP BY cust_name;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custname;
    END IF;
  END IF;

  IF (_custcount > 1) THEN
    RAISE EXCEPTION 'Found % possible Customers for % and % and %',
		    _custcount, _email, _company, _fullname;
  END IF;

  IF (_custcount <= 0 AND _generate) THEN
    IF (_company != '') THEN
      RETURN _company;
    ELSIF (_email != '') THEN
      RETURN _email;
    ELSIF (_fullname != '') THEN
      RETURN _fullname;
    ELSE
      RAISE EXCEPTION 'Could not generate a new Customer Name without an email address or the name of a company or person';
    END IF;
  END IF;

  IF (_custname IS NULL OR _custname = '') THEN
    RAISE EXCEPTION 'Could not find Customer Name for % and %',
		    _company, _fullname;
  END IF;

  RETURN _custname;
END;

Function: public.getcustnumberfrominfo(text, text, text, text, text, boolean)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _email	TEXT	:= COALESCE(UPPER($1), '');
  _company	TEXT	:= COALESCE(UPPER($2), '');
  _first	TEXT	:= COALESCE(UPPER($3), '');
  _last		TEXT	:= COALESCE(UPPER($4), '');
  _fullname	TEXT	:= COALESCE(UPPER($5), TRIM(_first || ' ' || _last));
  _generate	BOOLEAN	:= COALESCE($6, FALSE);
  _counter	INTEGER;
  _custcount	INTEGER	:= 0;
  _custnumber	TEXT;
  _candidate	TEXT	:= '';
  _loopmax	INTEGER := 0;
  _minlength	INTEGER := 5;
  _maxlength	INTEGER := 8;
  _numformat	TEXT	:= '';
  _testme	TEXT;
BEGIN
  IF (_email != '') THEN
    SELECT count(*), cust_number INTO _custcount, _custnumber
    FROM custinfo LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
    WHERE (UPPER(cntct_email)=_email)
    GROUP BY cust_number;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custnumber;
    END IF;
  END IF;

  IF (_company != '') THEN
    SELECT count(*), cust_number INTO _custcount, _custnumber
    FROM custinfo
    WHERE (UPPER(cust_name)=_company)
    GROUP BY cust_number;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custnumber;
    END IF;
  END IF;

  IF (_fullname = '' AND (_first != '' OR _last != '')) THEN
    _fullname := TRIM(_first || ' ' || _last);
  END IF;

  IF (_custcount <= 0 AND _fullname != '') THEN
    SELECT count(*), cust_number INTO _custcount, _custnumber
    FROM custinfo
    WHERE (UPPER(cust_name)=_fullname)
    GROUP BY cust_number;
    IF (NOT FOUND) THEN
      _custcount := 0;
    ELSIF(_custcount = 1) THEN
      RETURN _custnumber;
    END IF;
  END IF;

  IF (_custcount > 1) THEN
    RAISE EXCEPTION 'Found % possible Customers for % and % and %',
		    _custcount, _email, _company, _fullname;
  END IF;

  IF (_custcount <= 0 AND _generate) THEN
    IF (_maxlength < _minlength) THEN
      RAISE EXCEPTION 'Fix getCustNumberFromInfo: max length < min length';
    END IF;

    IF (_company != '') THEN
      _candidate := _company;
    ELSIF (_email != '') THEN
      _candidate := SUBSTRING(_email FOR POSITION('@' IN _email) - 1);
    ELSIF (_last != '') THEN
      _candidate := _last;
      IF (_first != '') THEN
	_candidate := _candidate || _first;
      END IF;
    ELSIF (_fullname != '' AND (POSITION(' ' IN _fullname) > 0)) THEN
      _candidate := SUBSTRING(_fullname FROM POSITION(' ' IN _fullname) + 1) ||
		    SUBSTRING(_fullname FOR  POSITION(' ' IN _fullname) - 1);
    END IF;
    WHILE (POSITION(' ' IN _candidate) > 0) LOOP
      _candidate := SUBSTRING(_candidate FOR  POSITION(' ' IN _candidate) - 1) ||
		    SUBSTRING(_candidate FROM POSITION(' ' IN _candidate) + 1);
    END LOOP;
    FOR _counter IN _minlength.._maxlength LOOP
      _testme := SUBSTRING(_candidate FOR _counter);
      IF (NOT EXISTS(SELECT cust_number
		     FROM custinfo
		     WHERE (cust_number=_testme))) THEN
	_custnumber := _testme;
	EXIT;
      END IF;
    END LOOP;
    IF (_custnumber IS NULL OR _custnumber = '') THEN
      IF (LENGTH(_candidate) < _minlength) THEN
	_minlength := LENGTH(_candidate);
      END IF;
      FOR _counter IN _minlength.._maxlength LOOP
	_loopmax := _loopmax * 10 + 9;
	_numformat := _numformat || '0';
      END LOOP;
      FOR _counter IN 1.._loopmax LOOP
	_testme := SUBSTRING(_candidate FOR _minlength) ||
		   TRIM(TO_CHAR(_counter, _numformat));
	IF (NOT EXISTS(SELECT cust_number
		       FROM custinfo
		       WHERE (cust_number=_testme))) THEN
	  _custnumber := _testme;
	  EXIT;
	END IF;
      END LOOP;
    END IF;
    IF (_custnumber IS NULL OR _custnumber = '') THEN
      RAISE EXCEPTION 'Could not generate a new Customer Number';
    END IF;
  END IF;

  IF (_custnumber IS NULL OR _custnumber = '') THEN
    RAISE EXCEPTION 'Could not find Customer Number for % and % and %',
		    _email, _company, _fullname;
  END IF;

  RETURN _custnumber;
END;

Function: public.getcusttypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustTypeCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pCustTypeCode IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT custtype_id INTO _returnVal
  FROM custtype
  WHERE (custtype_code=pCustTypeCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Customer Type % not found.', pCustTypeCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getdeptid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pDeptNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pDeptNumber), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT dept_id INTO _returnVal
  FROM dept
  WHERE (UPPER(dept_number)=UPPER(pDeptNumber));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Department % not found.', pDeptNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getediprofileid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pEdiProfileName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pEdiProfileName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT pkghead_id INTO _returnVal
    FROM pkghead
   WHERE(pkghead_name='xtbatch');
  IF(NOT FOUND) THEN
    RETURN NULL;
  END IF;

  SELECT ediprofile_id INTO _returnVal
  FROM xtbatch.ediprofile
  WHERE (ediprofile_name=pEdiProfileName);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'EDI Profile % not found.', pEdiProfileName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getediprofilename(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pEdiProfileId ALIAS FOR $1;
  _returnVal TEXT;
BEGIN
  IF (pEdiProfileId IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT pkghead_name INTO _returnVal
    FROM pkghead
   WHERE(pkghead_name='xtbatch');
  IF(NOT FOUND) THEN
    RETURN NULL;
  END IF;

  SELECT ediprofile_name INTO _returnVal
  FROM xtbatch.ediprofile
  WHERE (ediprofile_id=pEdiProfileId);

  RETURN _returnVal;
END;

Function: public.geteffectivextuser()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
/*
  The default return value of this function is simply
  the user currently connected.
  
  Overload this function from another schema 
  to implement specific user handling from an external 
  application that uses connection pooling. 
  Use setEffectiveXtUser(text) to create a temporary table that 
  inserts user data that can in turn be used as a lookup 
  reference for an over loaded version of this function like so:
  
  SELECT effective_value
  FROM effective_user
  WHERE effective_key = 'username'
*/

  RETURN CURRENT_USER;

END;

Function: public.getempid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pEmpCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pEmpCode), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT emp_id INTO _returnVal
  FROM emp
  WHERE (UPPER(emp_code)=UPPER(pEmpCode));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Employee % not found.', pEmpCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getexpcatid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pExpcatCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pExpcatCode), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT expcat_id INTO _returnVal
  FROM expcat
  WHERE (expcat_code=UPPER(pExpcatCode));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Expense Category % not found.', pExpcatCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getflcoldata(bpchar, integer[], boolean)

Returns: SET OF flcoldata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInterval ALIAS FOR $1;
  pPeriodids ALIAS FOR $2;
  pBudgets ALIAS FOR $3;
  _row flcoldata%ROWTYPE;
  _r RECORD;
  _start DATE;
  _end DATE;
  _col INTEGER := 1;
  _count INTEGER;
  _i INTEGER := 1;
  _incr INTEGER := 1;

BEGIN

  IF (pBudgets) THEN
    _col := 2;
    _incr := 2;
  END IF;
  
  _count := ARRAY_UPPER(pPeriodIds,1);
  
  IF (pInterval = 'M') THEN
    FOR _i IN 1.._count
    LOOP
      SELECT period_start, period_end INTO _start, _end
      FROM period
      WHERE (period_id=pPeriodids[_i]);

      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + _incr;
    END LOOP;
  ELSIF (pInterval = 'Q') THEN
    FOR _i IN 1.._count
    LOOP
      SELECT min(qtr.period_start), max(qtr.period_end) INTO _start, _end
      FROM period cur
        JOIN period qtr ON (cur.period_yearperiod_id=qtr.period_yearperiod_id)
                        AND (cur.period_quarter=qtr.period_quarter)
      WHERE (cur.period_id=pPeriodids[_i]);

      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + _incr;
    END LOOP;
  ELSE
    FOR _i IN 1.._count
    LOOP
      SELECT yearperiod_start, yearperiod_end INTO _start, _end
      FROM period
        JOIN yearperiod ON (period_yearperiod_id=yearperiod_id)
      WHERE (period_id=pPeriodids[_i]);

      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + _incr;
    END LOOP;
  END IF;
  RETURN;

END;

Function: public.getflcoldata(integer, integer)

Returns: SET OF flcoldata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlcolid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  _row flcoldata%ROWTYPE;
  _r RECORD;
  _start DATE;
  _end DATE;
  _col INTEGER := 1;
  _mult INTEGER;

BEGIN

--Get Layout Data
  SELECT * INTO _r
  FROM flcol
  WHERE (flcol_id=pFlcolid);

-- Handle Month...
  IF (_r.flcol_month) THEN
    SELECT period_start, period_end INTO _start, _end
    FROM period
    WHERE (period_id=pPeriodid);
    
    IF (_r.flcol_showdb) THEN
      -- Debits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;

      -- Credits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;
    END IF;

    -- Month Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

    -- These don't have drill down
    IF (_r.flcol_prcnt) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_budget) THEN
      _col := _col + 1;
      IF (_r.flcol_budgetprcnt) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiff) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiffprcnt) THEN
        _col := _col + 1;
      END IF;
    END IF; 
  END IF;

-- Handle Quarter...
  IF (_r.flcol_quarter) THEN
    SELECT min(qtr.period_start), max(qtr.period_end) INTO _start, _end
    FROM period p
     JOIN period qtr ON (p.period_quarter=qtr.period_quarter)
                     AND (p.period_yearperiod_id=qtr.period_yearperiod_id)
    WHERE (p.period_id=pPeriodid);
    
    IF (_r.flcol_showdb) THEN
      -- Debits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;

      -- Credits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;
    END IF;

    -- Quarter Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

    -- These don't have drill down
    IF (_r.flcol_prcnt) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_budget) THEN
      _col := _col + 1;
      IF (_r.flcol_budgetprcnt) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiff) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiffprcnt) THEN
        _col := _col + 1;
      END IF;
    END IF; 
  END IF;

-- Handle Year...
  IF (_r.flcol_year) THEN
    SELECT yearperiod_start, period_end INTO _start, _end
    FROM period p
     JOIN yearperiod ON (period_yearperiod_id=yearperiod_id)
    WHERE (p.period_id=pPeriodid);
    
    IF (_r.flcol_showdb) THEN
      -- Debits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;

      -- Credits Column
      _row.flcoldata_column := _col;
      _row.flcoldata_start := _start;
      _row.flcoldata_end := _end;
      RETURN NEXT _row;
      _col := _col + 1;
    END IF;

    -- Year Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

    -- These don't have drill down
    IF (_r.flcol_prcnt) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_budget) THEN
      _col := _col + 1;
      IF (_r.flcol_budgetprcnt) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiff) THEN
        _col := _col + 1;
      END IF;
      IF (_r.flcol_budgetdiffprcnt) THEN
        _col := _col + 1;
      END IF;
    END IF;
  END IF;

  -- Handle Prior Month...
  IF (_r.flcol_priormonth) THEN
    SELECT prv.period_start, prv.period_end INTO _start, _end
    FROM period p
      JOIN period prv ON (prv.period_start < p.period_start)
    WHERE (p.period_id=pPeriodid)
    ORDER BY prv.period_start DESC
    LIMIT 1;

    -- Prior Month Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

    -- These don't have drill down
    IF (_r.flcol_priorprcnt) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_priordiff) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_priordiffprcnt) THEN 
      _col := _col + 1;
    END IF;
  END IF;

-- Handle Prior Quarter...
  IF (_r.flcol_priorquarter) THEN
    IF (_r.flcol_priortype = 'P') THEN
      -- Prior Quarter
      SELECT min(period_start), max(period_end)
      INTO _start, _end
      FROM (
        SELECT prv.period_start, prv.period_end, prv.period_quarter, prv.period_yearperiod_id
        FROM period p
          JOIN period prv ON (prv.period_start < p.period_start)
                          AND (prv.period_quarter != p.period_quarter)
        WHERE (p.period_id=pPeriodid)) data
      GROUP BY period_quarter, period_yearperiod_id
      ORDER BY min(period_start) DESC
      LIMIT 1;
    ELSE
      -- Prior Year Quarter
      SELECT min(period_start), max(period_end)
      INTO _start, _end
      FROM (
        SELECT prv.period_start, prv.period_end, prv.period_quarter, prv.period_yearperiod_id
        FROM period p
          JOIN period prv ON (prv.period_start < p.period_start)
                          AND (prv.period_yearperiod_id != p.period_yearperiod_id)
                          AND (prv.period_quarter = p.period_quarter)
        WHERE (p.period_id=pPeriodid)) data
      GROUP BY period_quarter, period_yearperiod_id
      ORDER BY min(period_start) DESC
      LIMIT 1;
    END IF;

    -- Prior Quarter Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

    -- These don't have drill down
    IF (_r.flcol_priorprcnt) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_priordiff) THEN 
      _col := _col + 1;
    END IF;
    IF (_r.flcol_priordiffprcnt) THEN 
      _col := _col + 1;
    END IF;
  END IF;

  -- Handle Prior Year...
  IF (_r.flcol_prioryear IN ('D','F')) THEN
    IF (_r.flcol_prioryear = 'D') THEN
      -- Prior Year to Date
      SELECT yearperiod_start, prv.period_end INTO _start, _end
      FROM period p
        JOIN period prv ON (prv.period_number = p.period_number)
                        AND (prv.period_yearperiod_id != p.period_yearperiod_id)
                        AND (prv.period_start < p.period_start)
        JOIN yearperiod ON (prv.period_yearperiod_id=yearperiod_id)   
      WHERE (p.period_id=pPeriodid)
      ORDER BY prv.period_start DESC
      LIMIT 1;
    ELSE
      -- Prior Full Year
      SELECT prv.yearperiod_start, prv.yearperiod_end INTO _start, _end
      FROM period p
        JOIN yearperiod cur ON (cur.yearperiod_id=p.period_yearperiod_id)
        JOIN yearperiod prv ON (prv.yearperiod_start < cur.yearperiod_start)
      WHERE (p.period_id=pPeriodid)
      ORDER BY prv.yearperiod_start DESC
      LIMIT 1;
    END IF;

    -- Prior Year Column
    _row.flcoldata_column := _col;
    _row.flcoldata_start := _start;
    _row.flcoldata_end := _end;
    RETURN NEXT _row;
    _col := _col + 1;

  END IF;

  RETURN;

END;

Function: public.getflstmthead(integer, integer)

Returns: SET OF flstmthead

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlcolid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  _row flstmthead%ROWTYPE;
  _p RECORD;
  _month TEXT;
  _qtr TEXT;
  _year TEXT;
  _prmonth TEXT;
  _prqtr TEXT;
  _pryear TEXT;
  _err TEXT;

BEGIN

  SELECT 'No Data' INTO _err;

--Get Layout Data
  SELECT flcol_priortype, flcol_prioryear INTO _p
  FROM flcol
  WHERE (flcol_id=pFlcolid);

--get data...
--...for current Month
        SELECT
          (CASE
                      WHEN period_name='' THEN
                        formatdate(period_start) || '-' || formatdate(period_end)
                      ELSE period_name
          END) INTO _month
        FROM period
        WHERE (period_id=pPeriodId);

        IF _month IS NULL THEN
          _month := _err;
        END IF;

--...for Quarter
        SELECT
          ('Q' || period_quarter || '-' || EXTRACT(year from yearperiod_end)) INTO _qtr
        FROM period, yearperiod
        WHERE ((period_id=pPeriodId)
        AND (period_yearperiod_id=yearperiod_id));

        IF _qtr IS NULL THEN
          _qtr := _err;
        END IF;

--...for Year
        SELECT
          COALESCE((CASE WHEN period_name='' THEN
                (formatdate(period_start) || '-' || formatdate(period_end) || ' YTD')
          ELSE (period_name || ' YTD')
          END),'No Data') INTO _year
        FROM period
        WHERE (period_id=pPeriodId);

        IF _year IS NULL THEN
          _year := _err;
        END IF;

--...for prior month

        IF (_p.flcol_priortype = 'P') THEN

          SELECT
            (CASE WHEN pp.period_name='' THEN
              formatdate(pp.period_start) || '-' || formatdate(pp.period_end)
            ELSE pp.period_name END) INTO _prmonth
          FROM period cp, period pp
          WHERE ((cp.period_id=pPeriodId)
          AND (cp.period_start > pp.period_start))
          ORDER BY pp.period_start DESC LIMIT 1;

        ELSE

          SELECT
            (CASE WHEN pp.period_name='' THEN
              formatdate(pp.period_start) || '-' || formatdate(pp.period_end)
            ELSE pp.period_name END) INTO _prmonth
          FROM period cp, period pp
          WHERE ((cp.period_id=pPeriodId)
           AND (cp.period_id != pp.period_id)
           AND (cp.period_start > pp.period_start)
           AND (cp.period_number = pp.period_number))
          ORDER BY pp.period_start DESC LIMIT 1;

        END IF;

          IF _prmonth IS NULL THEN
            _prmonth := _err;
          END IF;


--...for prior quarter

        IF (_p.flcol_priortype='P') THEN

          SELECT ('Q' || pp.period_quarter || '-' || EXTRACT(year from yearperiod_end)) INTO _prqtr
          FROM period cp, period pp, yearperiod
          WHERE ((cp.period_id=pPeriodId)
          AND (cp.period_start > pp.period_start)
          AND (pp.period_quarter=
            CASE WHEN cp.period_quarter > 1 THEN
              cp.period_quarter - 1
          ELSE 4 END)
          AND (pp.period_start >= cp.period_start - interval '1 year')
          AND (pp.period_yearperiod_id=yearperiod_id))
          ORDER BY pp.period_start DESC LIMIT 1;

        ELSE

          SELECT
            ('Q' || pp.period_quarter || '-' || EXTRACT(year from pp.period_start)) INTO _prqtr
          FROM period cp, period pp, yearperiod cy, yearperiod py
          WHERE ((cp.period_id=pPeriodId)
          AND (cp.period_yearperiod_id=cy.yearperiod_id)
          AND (pp.period_yearperiod_id=py.yearperiod_id)
          AND (cp.period_quarter=pp.period_quarter)
          AND (cy.yearperiod_start > py.yearperiod_start))
          ORDER BY py.yearperiod_start DESC, pp.period_start DESC LIMIT 1;

        END IF;

        IF _prqtr IS NULL THEN
          _prqtr := _err;
        END IF;

--...for prior year

        IF (_p.flcol_prioryear='F') THEN

          SELECT (EXTRACT(year from py.yearperiod_end)||'') INTO _pryear
          FROM period cp, yearperiod cy, yearperiod py
          WHERE ((cp.period_id=pPeriodId)
           AND (cp.period_yearperiod_id = cy.yearperiod_id)
           AND (cy.yearperiod_start > py.yearperiod_start))
          ORDER BY py.yearperiod_start DESC LIMIT 1;

        ELSE

          SELECT
          (CASE
                      WHEN pp.period_name='' THEN
                        formatdate(pp.period_start) || '-' || formatdate(pp.period_end) || ' YTD'
                      ELSE pp.period_name || ' YTD'
          END) INTO _pryear
          FROM period cp, period pp
          WHERE ((cp.period_id=pPeriodId)
            AND (cp.period_number = pp.period_number)
            AND (cp.period_start > pp.period_start))
          ORDER BY pp.period_start DESC LIMIT 1;

        END IF;

        IF _pryear IS NULL THEN
          _pryear := _err;
        END IF;

-- RETURN RESULTS

        SELECT
                flhead_id AS flstmthead_flhead_id,
                flcol_id AS flstmthead_flcol_id,
                pPeriodid AS flstmthead_period,
                getEffectiveXtUser() AS flstmthead_username,
                CASE
                        WHEN flhead_type = 'I' THEN 'Income Statement'
                        WHEN flhead_type = 'B' THEN 'Balance Sheet'
                        WHEN flhead_type = 'C' THEN 'Cash Flow Statement'
                        ELSE 'N/A'
                END AS flstmthead_flhead_typedescrip1,
                CASE
                        WHEN flhead_type = 'I' THEN 'Income'
                        WHEN flhead_type = 'B' THEN 'Balance'
                        WHEN flhead_type = 'C' THEN 'Cash'
                        ELSE 'N/A'
                END AS flstmthead_flhead_typedescrip2,
                flhead_name AS flstmthead_flhead_name,
                flcol_name AS flstmthead_flcol_name,
                _month AS flstmthead_month,
                _qtr AS flstmthead_qtr,
                _year AS flstmthead_year,
                _prmonth AS flstmthead_prmonth,
                _prqtr AS flstmthead_prqtr,
                _pryear AS flstmthead_pryear INTO _p
        FROM flhead,flcol
        WHERE ((flcol_id=pFlcolid)
        AND (flhead_id=flcol_flhead_id));

                _row.flstmthead_flhead_id := _p.flstmthead_flhead_id;
                _row.flstmthead_flcol_id := _p.flstmthead_flcol_id;
                _row.flstmthead_period_id := _p.flstmthead_period;
                _row.flstmthead_username := _p.flstmthead_username;
                _row.flstmthead_typedescrip1 := _p.flstmthead_flhead_typedescrip1;
                _row.flstmthead_typedescrip2 := _p.flstmthead_flhead_typedescrip2;
                _row.flstmthead_flhead_name := _p.flstmthead_flhead_name;
                _row.flstmthead_flcol_name := _p.flstmthead_flcol_name;
                _row.flstmthead_month := _p.flstmthead_month;
                _row.flstmthead_qtr := _p.flstmthead_qtr;
                _row.flstmthead_year := _p.flstmthead_year;
                _row.flstmthead_prmonth := _p.flstmthead_prmonth;
                _row.flstmthead_prqtr := _p.flstmthead_prqtr;
                _row.flstmthead_pryear := _p.flstmthead_pryear;

        RETURN NEXT _row;

END;

Function: public.getfltrendhead(integer, integer[], bpchar)

Returns: SET OF fltrendhead

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid ALIAS FOR $1;
  pPeriodids ALIAS FOR $2;
  pInterval ALIAS FOR $3;
  _row fltrendhead%ROWTYPE;
  _p RECORD;
  _count INTEGER;
  _i INTEGER;
  _t TEXT;
  _fld TEXT[];
  _type CHAR;

BEGIN

-- Validate Interval
   IF pInterval <> 'M' AND pInterval <> 'Q' AND pInterval <> 'Y' THEN
     RAISE EXCEPTION 'Invalid Interval --> %', pInterval;
   END IF;

   IF ARRAY_UPPER(pPeriodIds,1) <= 12 THEN
        _count := ARRAY_UPPER(pPeriodIds,1);
   ELSE
        _count := 12;
   END IF;

   SELECT flhead_type INTO _type FROM flhead WHERE flhead_id = pFlheadId;

--get data...
--...for Month
        IF (pInterval = 'M') THEN
                FOR _i IN 1.._count
                LOOP
                        SELECT
                        (CASE
                                WHEN period_name='' THEN
                                        formatdate(period_start) || '-' || formatdate(period_end)
                                ELSE period_name
                        END) INTO _t
                        FROM period
                        WHERE (period_id=pPeriodIds[_i]);

                        _fld[_i] := _t;

                END LOOP;

--...for Quarter
                ELSE IF (pInterval = 'Q') THEN
                        FOR _i IN 1.._count
                        LOOP
                                SELECT
                                        ('Q' || period_quarter || '-' || EXTRACT(year from yearperiod_end)) INTO _t
                                FROM period, yearperiod
                                WHERE ((period_id=pPeriodIds[_i])
                                AND (period_yearperiod_id=yearperiod_id));

                                        _fld[_i] := _t;

                        END LOOP;
--...for Year
                ELSE
                        FOR _i IN 1.._count
                        LOOP
                                SELECT (EXTRACT(year from yearperiod_end)||'') INTO _t
                                FROM period, yearperiod
                                WHERE ((period_id=pPeriodIds[_i])
                                AND (period_yearperiod_id=yearperiod_id));

                                _fld[_i] := _t;

                        END LOOP;
                END IF;
        END IF;


-- RETURN RESULTS

        SELECT
                flhead_id AS fltrendhead_flhead_id,
                getEffectiveXtUser() AS fltrendhead_username,
                CASE
                        WHEN flhead_type = 'I' THEN 'Income Statement'
                        WHEN flhead_type = 'B' THEN 'Balance Sheet'
                        WHEN flhead_type = 'C' THEN 'Cash Flow Statement'
                        ELSE 'Ad Hoc'
                END AS fltrendhead_flhead_typedescrip,
                flhead_name AS fltrendhead_flhead_name INTO _p
        FROM flhead
        WHERE (flhead_id=pFlheadId);

                _row.fltrendhead_flhead_id := _p.fltrendhead_flhead_id;
                _row.fltrendhead_username := _p.fltrendhead_username;
               _row.fltrendhead_typedescrip := _p.fltrendhead_flhead_typedescrip;
                _row.fltrendhead_flhead_name := _p.fltrendhead_flhead_name;
                _row.fltrendhead_fld1 := _fld[1];
                _row.fltrendhead_fld2 := _fld[2];
                _row.fltrendhead_fld3 := _fld[3];
                _row.fltrendhead_fld4 := _fld[4];
                _row.fltrendhead_fld5 := _fld[5];
                _row.fltrendhead_fld6 := _fld[6];
                _row.fltrendhead_fld7 := _fld[7];
                _row.fltrendhead_fld8 := _fld[8];
                _row.fltrendhead_fld9 := _fld[9];
                _row.fltrendhead_fld10 := _fld[10];
                _row.fltrendhead_fld11 := _fld[11];
                _row.fltrendhead_fld12 := _fld[12];
                IF (_type IN ('I','C')) THEN
                        _row.fltrendhead_grndttl := 'Total';
                END IF;

        RETURN NEXT _row;

END;

Function: public.getfreightclassid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFreightClassCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pFreightClassCode IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT freightclass_id INTO _returnVal
  FROM freightclass
  WHERE (freightclass_code=pFreightClassCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Freight Class % not found.', pFreightClassCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getfreighttaxtypeid()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _taxtypeid INTEGER;
BEGIN
  SELECT taxtype_id
    INTO _taxtypeid
    FROM taxtype
   WHERE (taxtype_name='Freight');

  RETURN _taxtypeid;
END;

Function: public.getgainlossaccntid(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntId ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF ( (pAccntId = 0) OR (pAccntId IS NULL) ) THEN
	RETURN 0;
  END IF;

  IF (fetchMetricValue('GLCompanySize') = 0) THEN
    _returnVal := fetchMetricValue('CurrencyGainLossAccount')::integer;
  ELSE
    SELECT company_gainloss_accnt_id INTO _returnVal
    FROM company
      JOIN accnt ON (company_number=accnt_company)
    WHERE (accnt_id=pAccntId);
  END IF;

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Currency Gain/Loss Account not found for %', formatGlAccountLong(pAccntId);
  END IF;

  RETURN _returnVal;
END;

Function: public.getglaccntid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGlAccnt ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pGlAccnt IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT accnt_id INTO _returnVal
  FROM accnt
  WHERE (formatglaccount(accnt_id)=pGlAccnt);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Account Number % not found.', pGlAccnt;
  END IF;

  RETURN _returnVal;
END;

Function: public.getglaccntid(text, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCompany ALIAS FOR $1;
  pProfit ALIAS FOR $2;
  pGlAccnt ALIAS FOR $3;
  pSub ALIAS FOR $4;
  _account TEXT;
  _returnVal INTEGER;
BEGIN
  IF (pGlAccnt IS NULL) THEN
	RETURN NULL;
  END IF;

  IF (pCompany is not null) THEN
    _account := pCompany || '-';
  END IF;

  IF (pProfit is not null) THEN
    _account := _account || pProfit || '-';
  END IF;
  IF (pGlAccnt is not null) THEN
    if (_account is null) then
	_account := pGlAccnt;
    else
	_account := _account || pGlAccnt;
    end if;
  END IF;

  IF (pSub is not null) THEN
    _account := _account || '-' || pSub;
  END IF;

  SELECT accnt_id INTO _returnVal
  FROM accnt
  WHERE (formatglaccount(accnt_id)=_account);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Account Number % not found.', _account;
  END IF;

  RETURN _returnVal;
END;

Function: public.getimageid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pImageName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pImageName), '') = '') THEN
    RETURN NULL;
  END IF;

  SELECT image_id INTO _returnVal
  FROM image
  WHERE (image_name=pImageName);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Image % not found.', pImageName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincdtcatid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncdtCatName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncdtCatName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdtcat_id INTO _returnVal
  FROM incdtcat
  WHERE (incdtcat_name=pIncdtCatName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Category Name % not found.', pIncdtCatName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincdtcrmacctid(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncidentNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncidentNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdt_crmacct_id INTO _returnVal
  FROM incdt
  WHERE (incdt_number=pIncidentNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Number % not found.', pIncidentNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincdtpriorityid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncdtPriorityName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncdtPriorityName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdtpriority_id INTO _returnVal
  FROM incdtpriority
  WHERE (incdtpriority_name=pIncdtPriorityName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Priority Name % not found.', pIncdtPriorityName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincdtresolutionid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncdtResolutionName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncdtResolutionName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdtresolution_id INTO _returnVal
  FROM incdtresolution
  WHERE (incdtresolution_name=pIncdtResolutionName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Resolution Name % not found.', pIncdtResolutionName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincdtseverityid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncdtSeverityName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncdtSeverityName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdtseverity_id INTO _returnVal
  FROM incdtseverity
  WHERE (incdtseverity_name=pIncdtSeverityName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Severity Name % not found.', pIncdtSeverityName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getincidentid(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIncidentNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pIncidentNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT incdt_id INTO _returnVal
  FROM incdt
  WHERE (incdt_number=pIncidentNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Incident Number % not found.', pIncidentNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getinvcheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pInvcNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT invchead_id INTO _returnVal
  FROM invchead
  WHERE (UPPER(invchead_invcnumber)=UPPER(pInvcNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Invoice % not found.', pInvcNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getinvcitemlotserial(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcitemid ALIAS FOR $1;
  _lotserial text;
  _r RECORD;
  _first BOOLEAN;
  _newMethod BOOLEAN;
BEGIN
 
  --Test to see if Lot/Serial Enabled
  SELECT metric_value INTO _lotserial
  FROM metric
  WHERE ((metric_name='LotSerialControl')
  AND (metric_value ='t'));

  IF (FOUND) THEN
    _lotserial := '';
    _first := true;

--  Two ways of doing this: old method and new method
--  First, find out if new method employed.
--  (new method is more accurate, but unfortunately no
--  way to migrate or correct old data.  Have to keep
--  old method in case someone reprints an old invoice.)

    SELECT (COUNT(*) > 0) INTO _newMethod 
    FROM shipitem 
    WHERE ((shipitem_invcitem_id=pInvcitemid)
    AND (shipitem_invhist_id IS NOT NULL));

    IF (_newMethod) THEN

      FOR _r IN SELECT DISTINCT ls_number
                FROM invdetail, invhist, shipitem, ls
               WHERE ((shipitem_invcitem_id=pInvcitemid)
                 AND  (shipitem_invhist_id=invhist_id)
                 AND  (invhist_id=invdetail_invhist_id)
                 AND  (invdetail_ls_id=ls_id)) LOOP
        IF (_first = false) THEN
          _lotserial := _lotserial || ', ';
        END IF;
        _lotserial := _lotserial || _r.ls_number;
        _first := false;
      END LOOP;

      RETURN _lotserial;
    ELSE
      -- Handle it old way
      FOR _r IN SELECT DISTINCT ls_number
                FROM ls, invdetail JOIN invhist ON (invdetail_invhist_id=invhist_id)
               WHERE ((invhist_transtype='SH')
                 AND  (invdetail_invcitem_id=pInvcitemid)
                 AND  (invdetail_ls_id=ls_id)) LOOP
        IF (_first = false) THEN
          _lotserial := _lotserial || ', ';
        END IF;
        _lotserial := _lotserial || _r.ls_number;
        _first := false;
      END LOOP;

      RETURN _lotserial;
    END IF;
  ELSE
    RETURN '';
  END IF;
  
END

Function: public.getipsheadid(pipsname text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;
BEGIN
  IF (pIpsName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT ipshead_id INTO _returnVal
  FROM ipshead
  WHERE (ipshead_name=pIpsName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Pricing Schedule % not found.', pIpsName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getipsitemid(ppriceuom text, pqtyuom text, pqtybreak numeric, pitemnumber text, pipsname text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;
  
BEGIN
  IF (pIpsName IS NULL AND pItemNumber IS NULL AND pQtyBreak IS NULL AND pQtyUom IS NULL AND pPriceUom IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT ipsitem_id INTO _returnVal
  FROM ipsiteminfo
  WHERE ((ipsitem_ipshead_id=getIpsheadId(pIpsName))
  AND (ipsitem_item_id=getItemId(pItemNumber))
  AND (ipsitem_qtybreak=pQtyBreak)
  AND (ipsitem_qty_uom_id=getUomId(pQtyUom))
  AND (ipsitem_price_uom_id=getUomId(pPriceUom)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Pricing Schedule Item for Schedule %, Item %,Qt Break %,Qty UOM %, Price UOM % not found.', 
	pIpsName, pItemNumber, pQtyBreak, pQtyUom, pPriceUom;
  END IF;

  RETURN _returnVal;
END;

Function: public.getipsprodcatid(pqtybreak text, pprodcat text, pipsname numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;
  
BEGIN
  IF (pIpsName IS NULL AND pProdCat IS NULL AND pQtyBreak IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT ipsitem_id INTO _returnVal
  FROM ipsiteminfo
  WHERE ((ipsitem_ipshead_id=getIpsheadId(pIpsName))
  AND (ipsitem_prodcat_id=getProdcatId(pProdCat))
  AND (ipsitem_qtybreak=pQtyBreak));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Pricing Schedule Product Category for Schedule %, Product Category %,Qt Break % not found.', 
	pIpsName, pProdCat, pQtyBreak;
  END IF;

  RETURN _returnVal;
END;

Function: public.getitemid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pItemNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT item_id INTO _returnVal
  FROM item
  WHERE (item_number=UPPER(pItemNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Item % not found.', pItemNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getitemidfromupc(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemUPC ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pItemUPC IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT item_id INTO _returnVal
  FROM item
  WHERE (item_upccode=UPPER(pItemUPC));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Item % not found.', pItemUPC;
  END IF;

  RETURN _returnVal;
END;

Function: public.getitemsiteid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehouseCode ALIAS FOR $1;
  pItemNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  SELECT getItemsiteId(pWarehouseCode,pItemNumber,'ALL') INTO _returnVal;

  RETURN _returnVal;
END;

Function: public.getitemsiteid(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehouseCode ALIAS FOR $1;
  pItemNumber ALIAS FOR $2;
  pType ALIAS FOR $3;
  _type TEXT;
  _p RECORD;
BEGIN
  IF ((pWarehouseCode IS NULL) OR (pItemNumber IS NULL)) THEN
	RETURN NULL;
  END IF;
 
  IF UPPER(pType) NOT IN ('ALL','ACTIVE','SOLD') THEN
    RAISE EXCEPTION 'Invalid Type %. Valid Itemsite types are ALL and SOLD', pType;
  END IF;

  SELECT * INTO _p
  FROM itemsite, item
  WHERE ((itemsite_item_id=item_id)
  AND (itemsite_warehous_id=getWarehousId(pWarehouseCode,'ALL'))
  AND (item_number=UPPER(pItemNumber)));

  IF NOT (FOUND) THEN
    RAISE EXCEPTION 'Item % not found in Warehouse %', pItemNumber, pWarehouseCode;
  ELSIF ((UPPER(pType)='ACTIVE') OR (UPPER(pType)='SOLD')) THEN
    IF NOT (_p.item_active) THEN
      RAISE EXCEPTION 'Item % is inactive.', pItemNumber;
    ELSE
      IF NOT (_p.itemsite_active) THEN
        RAISE EXCEPTION 'Item % is inactive in Warehouse %', pItemNumber, pWarehouseCode;
      ELSE
        IF ((UPPER(pType)='SOLD') AND NOT _p.item_sold) THEN
          RAISE EXCEPTION 'Item % is not sold', pItemNumber;
        ELSE
          IF ((UPPER(pType)='SOLD') AND NOT _p.itemsite_sold) THEN
            RAISE EXCEPTION 'Item % is not sold from Warehouse %', pItemNumber, pWarehouseCode;
          END IF;
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN _p.itemsite_id;
END;

Function: public.getitemsrcid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemNumber ALIAS FOR $1;
  pVendNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ((pItemNumber IS NULL) OR (pVendNumber IS NULL)) THEN
    RETURN NULL;
  END IF;

  SELECT itemsrc_id INTO _returnVal
  FROM itemsrc
  WHERE ((itemsrc_item_id=getItemId(pItemNumber))
  AND (itemsrc_vend_id=getVendId(pVendNumber)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Item Source Item % Vendor % not found.', pItemNumber,pVendNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getitemtaxtype(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pTaxzoneid ALIAS FOR $2;
  _taxtypeid INTEGER;
BEGIN
  SELECT itemtax_taxtype_id
    INTO _taxtypeid
    FROM itemtax
   WHERE ((itemtax_item_id=pItemid)
     AND  (itemtax_taxzone_id=pTaxzoneid));
  IF (NOT FOUND) THEN
    SELECT itemtax_taxtype_id
      INTO _taxtypeid
      FROM itemtax
     WHERE ((itemtax_item_id=pItemid)
       AND  (itemtax_taxzone_id IS NULL));
    IF (NOT FOUND) THEN
      RETURN NULL;
    END IF;
  END IF;

  RETURN _taxtypeid;
END;

Function: public.getlasttrialbalid(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAccntId ALIAS FOR $1;
  pPeriodId ALIAS FOR $2;
  _p RECORD;
  _accntType TEXT;
  _result NUMERIC;

BEGIN

  SELECT period_end,period_yearperiod_id INTO _p
  FROM period
  WHERE period_id=pPeriodId;

  SELECT accnt_type INTO _accntType
  FROM accnt
  WHERE accnt_id=pAccntId;

  IF (_accntType IN ('R','E')) THEN
        SELECT trialbal_id INTO _result
        FROM trialbal
        WHERE ((trialbal_accnt_id=pAccntId)
        AND (trialbal_period_id=pPeriodId));
  ELSE
        SELECT trialbal_id INTO _result
        FROM (SELECT trialbal_id
                FROM trialbal,period
                WHERE ((trialbal_accnt_id=pAccntId)
                AND (trialbal_period_id=period_id)
                AND (period_end <= _p.period_end)
                AND (period_yearperiod_id=_p.period_yearperiod_id))
                ORDER BY period_end DESC) AS data;
  END IF;

  RETURN _result;

END;

Function: public.getlocationid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehouse ALIAS FOR $1;
  pLocation ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (pLocation IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT location_id INTO _returnVal
  FROM location
  WHERE ((location_warehous_id=getWarehousId(pWarehouse,'ACTIVE'))
  AND (formatLocationname(location_id)=pLocation))
  LIMIT 1;

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Location % not found in Warehouse %.', pLocation, pWarehouse;
  END IF;

  RETURN _returnVal;
END;

Function: public.getlotserialid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemNumber ALIAS FOR $1;
  pLotSerialNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ((pItemNumber IS NULL) OR (pLotSerialNumber IS NULL) OR (pLotSerialNumber='')) THEN
	RETURN NULL;
  END IF;

  SELECT ls_id INTO _returnVal
  FROM ls
  WHERE ((ls_item_id=getItemId(pItemNumber))
  AND (UPPER(ls_number)=UPPER(pLotSerialNumber)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'LotSerial % not found.', pLotSerialNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getopheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOpHeadName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  
  IF (pOpHeadName IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT ophead_id INTO _returnVal
  FROM ophead
  WHERE (UPPER(ophead_name)=UPPER(pOpHeadName));
  
  IF (_returnVal IS NULL) THEN
      RAISE EXCEPTION 'Opportunity % not found.', pOpHeadName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getpacklistcharname(integer, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadId ALIAS FOR $1;
  pOrderItemId ALIAS FOR $2;
  _charname text;
  _r RECORD;
  _first BOOLEAN;
  
BEGIN

-- If transfer order, get out
  SELECT shiphead_order_type INTO _r
  FROM shiphead
  WHERE ((shiphead_id=pShipheadId)
  AND (shiphead_order_type='TO'));
  
  IF (FOUND) THEN
    RETURN '';
  END IF;

  _charname := '';
  _first := true;

  FOR _r IN SELECT char_name
            FROM char, charass
            WHERE ((char_id=charass_char_id)
            AND (charass_target_type='SI')
            AND (charass_target_id=pOrderItemId)) 
  LOOP
        IF (_first = false) THEN
          _charname := _charname || '
';
        END IF;
        _charname := _charname || _r.char_name;
        _first := false;
  END LOOP;

  RETURN _charname;
  
END

Function: public.getpacklistcharvalue(integer, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadId ALIAS FOR $1;
  pOrderItemId ALIAS FOR $2;
  _charval text;
  _r RECORD;
  _first BOOLEAN;
  
BEGIN

-- If transfer order, get out
  SELECT shiphead_order_type INTO _r
  FROM shiphead
  WHERE ((shiphead_id=pShipheadId)
  AND (shiphead_order_type='TO'));
  
  IF (FOUND) THEN
    RETURN '';
  END IF;

  _charval := '';
  _first := true;

  FOR _r IN SELECT charass_value
            FROM char, charass
            WHERE ((char_id=charass_char_id)
            AND (charass_target_type='SI')
            AND (charass_target_id=pOrderItemId)) 
  LOOP
        IF (_first = false) THEN
          _charval := _charval || '
';
        END IF;
        _charval := _charval || _r.charass_value;
        _first := false;
  END LOOP;

  RETURN _charval;
  
END

Function: public.getpacklistitemlotserial(integer, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadId ALIAS FOR $1;
  pOrderItemId ALIAS FOR $2;
  _lotserial text;
  _r RECORD;
  _first BOOLEAN;
  
BEGIN
 
  --Test to see if Lot/Serial Enabled
  SELECT metric_value INTO _lotserial
  FROM metric
  WHERE ((metric_name='LotSerialControl')
  AND (metric_value ='t'));

  IF (FOUND) THEN
    _lotserial := '';
    _first := true;

    FOR _r IN SELECT DISTINCT ls_number
              FROM invdetail, invhist, shipitem, ls
             WHERE ((shipitem_shiphead_id=pShipheadId)
               AND  (shipitem_orderitem_id=pOrderItemId)
               AND  (shipitem_invhist_id=invhist_id)
               AND  (invhist_id=invdetail_invhist_id)
               AND  (invdetail_ls_id=ls_id)) LOOP
      IF (_first = false) THEN
        _lotserial := _lotserial || ', ';
      END IF;
      _lotserial := _lotserial || _r.ls_number;
      _first := false;
    END LOOP;

    RETURN _lotserial;
  ELSE
    RETURN '';
  END IF;
  
END

Function: public.getperiodid(date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodDate ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pPeriodDate IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT period_id INTO _returnVal
  FROM period
  WHERE ((pPeriodDate) between period_start AND period_end);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Period for % not found.', pPeriodDate;
  END IF;

  RETURN _returnVal;
END;

Function: public.getperiodid(integer, bpchar)

Returns: SET OF integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodId ALIAS FOR $1;
  pInterval ALIAS FOR $2;
  _x RECORD;
BEGIN

-- Validate Interval
   IF pInterval <> 'M' AND pInterval <> 'Q' AND pInterval <> 'Y' THEN
     RAISE EXCEPTION 'Invalid Interval --> %', pInterval;
   END IF;

   IF pInterval='M' THEN
       RETURN NEXT pPeriodId;
     ELSE IF pInterval='Q' THEN
        FOR _x IN SELECT qp.period_id AS period_id
                FROM period cp, period qp
                WHERE ((cp.period_id=pPeriodId)
                AND (cp.period_yearperiod_id=qp.period_yearperiod_id)
                AND (cp.period_quarter=qp.period_quarter)
                AND (cp.period_start>=qp.period_start))
        ORDER BY qp.period_start
        LOOP
                RETURN NEXT _x.period_id;
        END LOOP;
     ELSE
        FOR _x IN SELECT yp.period_id AS period_id
                FROM period cp, period yp
                WHERE ((cp.period_id=pPeriodId)
                AND (cp.period_yearperiod_id=yp.period_yearperiod_id)
                AND (cp.period_start>=yp.period_start))
        ORDER BY yp.period_start
        LOOP
                RETURN NEXT _x.period_id;
        END LOOP;
     END IF;
   END IF;
  RETURN;
END;

Function: public.getpkgheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ppkgname ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (ppkgname IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT pkghead_id INTO _returnVal
  FROM pkghead
  WHERE (UPPER(pkghead_name)=UPPER(ppkgname));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Package % not found.', ppkgname;
  END IF;

  RETURN _returnVal;
END;

Function: public.getplancodeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPlanCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pPlanCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT plancode_id INTO _returnVal
  FROM plancode
  WHERE (plancode_code=pPlanCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Plan Code % not found.', pPlanCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getpoheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPurchaseOrderNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pPurchaseOrderNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT pohead_id INTO _returnVal
  FROM pohead
  WHERE (pohead_number=pPurchaseOrderNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Purchase Order % not found.', pPurchaseOrderNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getpoitemid(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPurchaseOrderNumber	ALIAS FOR $1;
  pLineNumber 	    	ALIAS FOR $2;
  _returnVal 		INTEGER;
BEGIN
  IF (pPurchaseOrderNumber IS NULL OR pLineNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT poitem_id INTO _returnVal
  FROM pohead, poitem
  WHERE ((pohead_number=pPurchaseOrderNumber)
  AND (poitem_pohead_id=pohead_id)
  AND (poitem_linenumber=pLineNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Purchase Order % not found.', pSalesOrderNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getprjaccntid(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjid ALIAS FOR $1;
  pAccntid ALIAS FOR $2;
  
BEGIN
  -- Project Accounting is required to fully implement this functionality
  RETURN pAccntId;
END;

Function: public.getprjid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pPrjNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT prj_id INTO _returnVal
  FROM prj
  WHERE (prj_number=pPrjNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Project Number % not found.', pPrjNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getprjtaskid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrjNumber ALIAS FOR $1;
  pTaskNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF (pPrjNumber IS NULL OR pTaskNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT prjtask_id INTO _returnVal
  FROM prjtask
    JOIN prj ON (prj_id=prjtask_prj_id)
  WHERE ((prj_number=pPrjNumber)
  AND (prjtask_number=pTaskNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Project Task Number %-% not found.', pPrjNumber, pTaskNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getprodcatid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pProdCat ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pProdCat IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT prodcat_id INTO _returnVal
  FROM prodcat
  WHERE (prodcat_code=pProdCat);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Product Category % not found.', pProdCat;
  END IF;

  RETURN _returnVal;
END;

Function: public.getprospectid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pProspectNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pProspectNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT prospect_id INTO _returnVal
    FROM prospect
   WHERE(UPPER(prospect_number)=UPPER(pProspectNumber));
  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Prospect Number % found.', pProspectNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getquoteid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuoteNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pQuoteNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT quhead_id INTO _returnVal
  FROM quhead
  WHERE (quhead_number=pQuoteNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Quote Number % not found.', pQuoteNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getquotelineitemid(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuoteNumber ALIAS FOR $1;
  pLineNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ((pQuoteNumber IS NULL) OR (pLineNumber IS NULL)) THEN
    RETURN NULL;
  END IF;

  SELECT quitem_id INTO _returnVal
  FROM quhead, quitem
  WHERE ((quhead_number=pQuoteNumber)
  AND (quhead_id=quitem_quhead_id)
  AND (quitem_linenumber=pLineNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Quote Line Item %-%not found.', pQuoteNumber,pLineNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getrevid(text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pType ALIAS FOR $1;
  pItemNumber ALIAS FOR $2;
  pRevision ALIAS FOR $3;
  _returnVal INTEGER;
BEGIN
  IF (pItemNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  IF (NOT fetchMetricBool('RevControl')) THEN
    RETURN -1;
  ELSIF ( (pRevision IS NULL) OR (LENGTH(pRevision)=0) ) THEN
    SELECT getActiveRevId(pType, getItemId(pItemNumber)) INTO _returnVal;
  ELSE
    IF (pType='BOM') THEN
      SELECT rev_id INTO _returnVal
      FROM item, bomhead, rev
      WHERE ((item_id=bomhead_item_id)
      AND (bomhead_rev_id=rev_id)
      AND (UPPER(item_number)=UPPER(pItemNumber))
      AND (rev_number=pRevision));
    ELSIF (pType='BOO') THEN
      SELECT rev_id INTO _returnVal
      FROM item, xtmfg.boohead, rev
      WHERE ((item_id=boohead_item_id)
      AND (boohead_rev_id=rev_id)
      AND (UPPER(item_number)=UPPER(pItemNumber))
      AND (rev_number=pRevision));   
    ELSE
      RAISE EXCEPTION 'Invalid Revision Type.';
    END IF;
  END IF;
    
  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION '% revision % for % not found.', pType, pRevision, pItemNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getrsnid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pRsnCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pRsnCode IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT rsncode_id INTO _returnVal
  FROM rsncode
  WHERE (rsncode_code=pRsnCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Reason Code % not found.', pRsnCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsalescatid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesCatName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSalesCatName IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT salescat_id INTO _returnVal
  FROM salescat
  WHERE (salescat_name=pSalesCatName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Category % not found.', pSalesCatName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsaleslineitemid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesOrderItem ALIAS FOR $1;
  _delpos INTEGER = 0;
  _order TEXT;
  _part TEXT;
  _ln INTEGER;
  _sn INTEGER;
BEGIN
  IF (pSalesOrderItem IS NULL) THEN
    RETURN NULL;
  END IF;
  _delpos := strpos(pSalesOrderItem, '-');
  IF (_delpos > 0) THEN
    _order := substr(pSalesOrderItem, 1, (_delpos - 1));
    _part := substr(pSalesOrderItem, (_delpos + 1));
    _delpos := strpos(_part, '.');
    IF (_delpos > 0) THEN
      _ln := CAST(substr(_part, 1, (_delpos - 1)) AS INTEGER);
      _sn := CAST(substr(_part, (_delpos + 1)) AS INTEGER);
    ELSE
      _ln := CAST(_part AS INTEGER);
      _sn := 0;
    END IF;
    RETURN getSalesLineItemId( _order, _ln, _sn );
  END IF;
  RETURN 0;
END;

Function: public.getsaleslineitemid(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN getSalesLineItemId($1, $2, 0);
END

Function: public.getsaleslineitemid(text, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesOrderNumber ALIAS FOR $1;
  pLineNumber ALIAS FOR $2;
  pSubNumber ALIAS FOR $3;
  _returnVal INTEGER;
BEGIN
  IF ((pSalesOrderNumber IS NULL) OR (pLineNumber IS NULL)) THEN
    RETURN NULL;
  END IF;

  SELECT coitem_id INTO _returnVal
  FROM cohead, coitem
  WHERE ((cohead_number=pSalesOrderNumber)
  AND (cohead_id=coitem_cohead_id)
  AND (coitem_linenumber=pLineNumber)
  AND (coitem_subnumber=pSubNumber));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Line Item %-%not found.', pSalesOrderNumber,pLineNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsalesorderid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesOrderNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSalesOrderNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT cohead_id INTO _returnVal
  FROM cohead
  WHERE (cohead_number=pSalesOrderNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Order Number % not found.', pSalesOrderNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsalesrepid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSalesRepNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSalesRepNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT salesrep_id INTO _returnVal
  FROM salesrep
  WHERE (salesrep_number=pSalesRepNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sales Rep Number % not found.', pSalesRepNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsaletypeid(psaletype text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;
BEGIN
  IF (pSaleType IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT saletype_id INTO _returnVal
  FROM saletype
  WHERE (saletype_code=pSaleType);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Sale Type % not found.', pSaleType;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshiftid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShiftNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (COALESCE(TRIM(pShiftNumber), '') = '') THEN
      RETURN NULL;
  END IF;

  SELECT shift_id INTO _returnVal
  FROM shift
  WHERE (UPPER(shift_number)=UPPER(pShiftNumber));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Shift % not found.', pShiftNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshipchrgid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipChrgName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pShipChrgName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT shipchrg_id INTO _returnVal
  FROM shipchrg
  WHERE (shipchrg_name=pShipChrgName);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Ship Charge % not found.', pShipChrgName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshipformid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipFormName ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pShipFormName IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT shipform_id INTO _returnVal
  FROM shipform
  WHERE (shipform_name=pShipFormName) LIMIT 1;

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Ship Form % not found.', pShipFormName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshipheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipmentNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pShipmentNumber IS NULL OR pShipmentNumber = '') THEN
    RETURN NULL;
  END IF;

  SELECT shiphead_id INTO _returnVal
  FROM shiphead
  WHERE (shiphead_number=pShipmentNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Shipment % not found.', pShipmentNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshiptoid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustNumber ALIAS FOR $1;
  pShiptoNumber ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ((pCustNumber IS NULL) OR (pShiptoNumber IS NULL)) THEN
	RETURN NULL;
  END IF;

  SELECT shipto_id INTO _returnVal
  FROM shiptoinfo
  WHERE ((shipto_cust_id=getCustId(pCustNumber,true))
  AND (UPPER(shipto_num)=UPPER(pShiptoNumber)));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Shipto % not found.', pShiptoNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshiptonumberfrominfo(text, text, text, text, text, text, text, text, text, text, text, text, text, boolean, boolean)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _custname TEXT := COALESCE(TRIM(UPPER( $1)), '');
  _email TEXT 	 := COALESCE(TRIM(UPPER( $2)), '');
  _company TEXT  := COALESCE(TRIM(UPPER( $3)), '');
  _first TEXT 	 := COALESCE(TRIM(UPPER( $4)), '');
  _last TEXT 	 := COALESCE(TRIM(UPPER( $5)), '');
  _fullname TEXT := COALESCE(TRIM(UPPER( $6)), '');
  _addr1 TEXT 	 := COALESCE(TRIM(UPPER( $7)), '');
  _addr2 TEXT 	 := COALESCE(TRIM(UPPER( $8)), '');
  _addr3 TEXT 	 := COALESCE(TRIM(UPPER( $9)), '');
  _city TEXT 	 := COALESCE(TRIM(UPPER($10)), '');
  _state TEXT 	 := COALESCE(TRIM(UPPER($11)), '');
  _postalcode TEXT := COALESCE(TRIM(UPPER($12)), '');
  _country TEXT  := COALESCE(TRIM(UPPER($13)), '');
  _generate BOOLEAN := COALESCE($14, FALSE);
  _create BOOLEAN := COALESCE($15, FALSE);

  _citytrunc TEXT;
  _counter INTEGER;
  _custid INTEGER;
  _custnumber TEXT;
  _candidate TEXT;
  _r RECORD;
  _statetrunc TEXT;
BEGIN
  IF (_custname = '') THEN
    _custname := getCustNameFromInfo(_email, _company, _first, _last,
                     _fullname, FALSE);
  END IF;


  SELECT COUNT(*) INTO _counter
  FROM custinfo, shiptoinfo, addr
  WHERE ((UPPER(cust_name)=UPPER(_custname))
    AND UPPER(shipto_name)=UPPER(_fullname)
    AND (cust_id=shipto_cust_id)
    AND (shipto_addr_id=addr_id));

  IF (_counter = 1) THEN
    SELECT shipto_num INTO _candidate
    FROM custinfo, shiptoinfo, addr
    WHERE ((UPPER(cust_name)=UPPER(_custname))
      AND UPPER(shipto_name)=UPPER(_fullname)
      AND (cust_id=shipto_cust_id)
      AND (shipto_addr_id=addr_id));

    RETURN _candidate;

  ELSE

    SELECT COUNT(*) INTO _counter
    FROM custinfo, shiptoinfo, addr
    WHERE ((UPPER(cust_name)=UPPER(_custname))
      AND (cust_id=shipto_cust_id)
      AND (shipto_addr_id=addr_id));

    IF (_counter = 1) THEN
      SELECT shipto_num INTO _candidate
      FROM custinfo, shiptoinfo, addr
      WHERE ((UPPER(cust_name)=UPPER(_custname))
        AND (cust_id=shipto_cust_id)
        AND (shipto_addr_id=addr_id));

      RETURN _candidate;

    ELSIF (_counter > 1) THEN
      SELECT shipto_num,
         CASE WHEN (UPPER(addr_country) = _country) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_postalcode) = _postalcode) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_state) = _state) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_city) = _city) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_line3) = _addr3) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_line2) = _addr2) THEN 1 ELSE 0 END +
         CASE WHEN (UPPER(addr_line1) = _addr1) THEN 1 ELSE 0 END
         AS maxquotient INTO _candidate, _counter
      FROM custinfo, shiptoinfo, addr
      WHERE ((UPPER(cust_name)=_custname)
        AND (cust_id=shipto_cust_id)
        AND (shipto_addr_id=addr_id))
      ORDER BY maxquotient desc
      LIMIT 1;

      RETURN _candidate;
    END IF;
  END IF;

  IF (_generate) THEN
    SELECT cust_number, cust_id INTO _custnumber, _custid
    FROM custinfo
    WHERE (UPPER(cust_name)=_custname);

    -- keep the number short
    _citytrunc := SUBSTRING(_city FOR 5);
    _statetrunc := SUBSTRING(_state FOR 5);

    IF (LENGTH(_citytrunc) > 0 AND NOT EXISTS(SELECT UPPER(shipto_num)
              FROM shiptoinfo
              WHERE ((shipto_cust_id=_custid)
                AND (UPPER(shipto_num)=_citytrunc)) )) THEN
      _candidate := _citytrunc;
    ELSIF (LENGTH(_last || _citytrunc) > 0 AND NOT EXISTS(SELECT UPPER(shipto_num)
              FROM shiptoinfo
              WHERE ((shipto_cust_id=_custid)
                AND (UPPER(shipto_num)=_last || _citytrunc)) )) THEN
      _candidate := _last || _citytrunc;
    ELSIF (LENGTH(_statetrunc) > 0 AND NOT EXISTS(SELECT UPPER(shipto_num)
           FROM shiptoinfo
           WHERE ((shipto_cust_id=_custid)
             AND (UPPER(shipto_num)=_statetrunc)) )) THEN
      _candidate := _statetrunc;
    ELSIF (LENGTH(_last || _statetrunc) > 0 AND NOT EXISTS(SELECT UPPER(shipto_num)
           FROM shiptoinfo
           WHERE ((shipto_cust_id=_custid)
             AND (UPPER(shipto_num)=_last || _statetrunc)) )) THEN
      _candidate := _last || _statetrunc;

    ELSIF (LENGTH(_citytrunc || _statetrunc) > 0 AND NOT EXISTS(SELECT UPPER(shipto_num)
              FROM shiptoinfo
              WHERE ((shipto_cust_id=_custid)
                AND (UPPER(shipto_num)=_citytrunc || _statetrunc)) )) THEN
      _candidate := _citytrunc || _statetrunc;

    ELSE
      SELECT CAST(COALESCE(MAX(CAST(shipto_num AS INTEGER)), 0) + 1 AS TEXT)
      INTO _candidate
      FROM shiptoinfo
      WHERE ((shipto_cust_id=_custid)
       AND (shipto_num~'^[0-9]*$'));
    END IF;

    IF (_create) THEN
      INSERT INTO api.custshipto (
    customer_number, shipto_number, name,
    address1, address2, address3,
    city, state, postal_code, country, address_change,
    first, last, email,
    edi_profile
      ) VALUES (
    _custnumber, _candidate, _candidate,
    _addr1, _addr2, _addr3,
    _city, _state, _postalcode, _country, 'CHANGEONE',
    _first, _last, LOWER(_email),
    'No EDI'
      );
    END IF;

    RETURN _candidate;
  END IF;

  RETURN '';
END;

Function: public.getshipviaid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipViaCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pShipViaCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT shipvia_id INTO _returnVal
  FROM shipvia
  WHERE (shipvia_code=pShipViaCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'ShipVia Code % not found.', pShipViaCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getshipzoneid(pshipzonename text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;
BEGIN
  IF (pShipZoneName IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT shipzone_id INTO _returnVal
  FROM shipzone
  WHERE (shipzone_name=pShipZoneName);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Ship Zone % not found.', pShipZoneName;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsitetypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSiteType ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSiteType IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT sitetype_id INTO _returnVal
  FROM sitetype
  WHERE (sitetype_name=pSiteType);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Site Type % not found.', pSiteType;
  END IF;

  RETURN _returnVal;
END;

Function: public.getsoscheddate(integer)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoheadid ALIAS FOR $1;
  _minscheddate DATE;

BEGIN

  SELECT MIN(coitem_scheddate) INTO _minscheddate
  FROM coitem
  WHERE ( (coitem_cohead_id=pCoheadid)
    AND   (coitem_status NOT IN ('C', 'X')) );

  RETURN _minscheddate;

END;

Function: public.getsostatus(integer)

Returns: bpchar

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCoheadid ALIAS FOR $1;
  _result char(1);

BEGIN

  SELECT cohead_status INTO _result
  FROM cohead
  WHERE (cohead_id=pCoheadid);

  RETURN _result;

END;

Function: public.getsubtax(integer, integer)

Returns: SET OF subtax

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxCodeId ALIAS FOR $1;
  pLevel ALIAS FOR $2;
  _row subtax%ROWTYPE;
  _x RECORD;
  _y RECORD;

BEGIN

  FOR _x IN --Select all tax codes whose calculation basis is pTaxCodeId
    SELECT tax_id, tax_code, tax_descrip
    FROM tax
    WHERE tax_basis_tax_id = pTaxCodeId
    
    
    LOOP
    _row.subtax_taxcode_id := _x.tax_id;
    _row.subtax_taxcode_code := _x.tax_code;
    _row.subtax_taxcode_descrip := _x.tax_descrip;
    _row.subtax_taxcode_level := pLevel + 1;

   RETURN NEXT _row;  
  
    FOR _y IN SELECT * from getSubTax(_x.tax_id, pLevel + 1) --This is the recursive part.
    LOOP

      _row.subtax_taxcode_id := _y.subtax_taxcode_id;
      _row.subtax_taxcode_code := _y.subtax_taxcode_code ;
      _row.subtax_taxcode_descrip := _y.subtax_taxcode_descrip;
      _row.subtax_taxcode_level := pLevel + 2;

      RETURN NEXT _row;

    END LOOP;
 
  END LOOP;

END;

Function: public.gettaxauthid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxAuthCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pTaxAuthCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT taxauth_id INTO _returnVal
  FROM taxauth
  WHERE (taxauth_code=pTaxAuthCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Tax Authority % not found.', pTaxAuthCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.gettaxid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pTaxCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT tax_id INTO _returnVal
  FROM tax
  WHERE (tax_code=pTaxCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Tax Code % not found.', pTaxCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.gettaxtypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxType ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pTaxType IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT taxtype_id INTO _returnVal
  FROM taxtype
  WHERE (taxtype_name=pTaxType);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Tax Type % not found.', pTaxType;
  END IF;

  RETURN _returnVal;
END;

Function: public.gettaxzoneid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxZone ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pTaxZone IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT taxzone_id INTO _returnVal
  FROM taxzone
  WHERE (taxzone_code=pTaxZone);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Tax Zone % not found.', pTaxZone;
  END IF;

  RETURN _returnVal;
END;

Function: public.gettermsid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTermsCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pTermsCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT terms_id INTO _returnVal
  FROM terms
  WHERE (terms_code=pTermsCode);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Terms Code % not found.', pTermsCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getunassignedaccntid()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _test INTEGER;
  _returnVal INTEGER;
BEGIN
  SELECT fetchMetricValue('UnassignedAccount') INTO _test;

  IF (_test IS NULL) THEN
    RAISE EXCEPTION 'Metric not found for UnassignedAccount';
  END IF;

  SELECT accnt_id INTO _returnVal
  FROM accnt
  WHERE (accnt_id=_test);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Metric UnassignedAccount is an invalid G/L Account';
  END IF;

  RETURN _returnVal;
END;

Function: public.getuomid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUom ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pUom IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT uom_id INTO _returnVal
  FROM uom
  WHERE (uom_name=pUom);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Unit of Measure % not found.', pUom;
  END IF;

  RETURN _returnVal;
END;

Function: public.getuomtypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUomType ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pUomType IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT uomtype_id INTO _returnVal
  FROM uomtype
  WHERE (UPPER(uomtype_name)=UPPER(pUomType));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Unit of Measuer Type % not found.', pUomType;
  END IF;

  RETURN _returnVal;
END;

Function: public.getuomtypeid(text[])

Returns: integer[]

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUomTypes ALIAS FOR $1;
  _returnVal INTEGER[];
  _val INTEGER;
  _i INTEGER;
BEGIN
  IF (pUomTypes IS NULL) OR (ARRAY_UPPER(pUomTypes,1) = 0) THEN
	RETURN NULL;
  END IF;

  FOR _i IN 1..ARRAY_UPPER(pUomTypes,1)
  LOOP
    SELECT uomtype_id INTO _val
    FROM uomtype
    WHERE (UPPER(uomtype_name)=UPPER(pUomTypes[_i]));

    IF (_val IS NULL) THEN
	RAISE EXCEPTION 'Unit of Measure Type % not found.', pUomTypes[_i];
    ELSE
      _returnVal[_i] := _val;
    END IF;
  END LOOP;

  RETURN _returnVal;
END;

Function: public.getusrid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsr ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  SELECT usr_id INTO _returnVal
  FROM usr
  WHERE (usr_username=COALESCE(pUsr, getEffectiveXtUser()));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'User % not found.', pUsr;
  END IF;

  RETURN _returnVal;
END;

Function: public.getvendaddrid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendNumber   ALIAS FOR $1;
  pVendAddrCode ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ( (pVendNumber IS NULL) OR (pVendAddrCode IS NULL) ) THEN
    RETURN NULL;
  END IF;

  SELECT vendaddr_id INTO _returnVal
    FROM vendaddrinfo
    JOIN vendinfo ON (vend_id=vendaddr_vend_id)
  WHERE ( (vendaddr_code=pVendAddrCode)
    AND   (vend_number=pVendNumber) );

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Vendor Number % Address % not found.',
    pVendNumber, pVendAddrCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getvendid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pVendNumber IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT vend_id INTO _returnVal
    FROM vendinfo
   WHERE (vend_number=pVendNumber);

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Vendor Number % not found.', pVendNumber;
  END IF;

  RETURN _returnVal;
END;

Function: public.getvendtypeid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendTypeCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pVendTypeCode IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT vendtype_id INTO _returnVal
  FROM vendtype
  WHERE (UPPER(vendtype_code)=UPPER(pVendTypeCode));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Vendor Type % not found.', pVendTypeCode;
  END IF;

  RETURN _returnVal;
END;

Function: public.getwarehousid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousCode ALIAS FOR $1;
  pType ALIAS FOR $2;
  _active BOOL;
  _shipping BOOL;
  _returnVal INTEGER;
BEGIN
  IF (pWarehousCode IS NULL) THEN
	RETURN NULL;
  END IF;
 
  IF (UPPER(pType) NOT IN ('ALL','ACTIVE','SHIPPING')) THEN
    	RAISE EXCEPTION 'Warehouse lookip type % not valid. Valid types are ALL, ACTIVE and SHIPPING', pType;
  END IF;

  SELECT warehous_id, warehous_active, warehous_shipping INTO _returnVal, _active, _shipping
  FROM site()
  WHERE (warehous_code=UPPER(pWarehousCode));

  IF (_returnVal IS NULL) THEN
    RAISE EXCEPTION 'Warehouse Code % not found.', pWarehousCode;
    ELSE IF ((pType='SHIPPING') AND (_shipping=false)) THEN
      RAISE EXCEPTION 'Warehouse Code % is not a vaild shipping warehouse.', pWarehousCode;
      ELSE IF ((pType IN ('SHIPPING','ACTIVE')) AND (_active=false)) THEN
        RAISE EXCEPTION 'Warehouse Code % is inactive.', pWarehousCode;
      END IF;
    END IF;
  END IF;

  RETURN _returnVal;
END;

Function: public.getwhsezoneid(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWhseCode ALIAS FOR $1;
  pWhseZoneName ALIAS FOR $2;
  _returnVal INTEGER;
BEGIN
  IF ((pWhseCode IS NULL) OR (pWhseZoneName IS NULL)) THEN
	RETURN NULL;
  END IF;

  SELECT whsezone_id INTO _returnVal
  FROM whsezone
  WHERE ( (whsezone_warehous_id=getWarehousId(pWhseCode, 'ACTIVE'))
      AND (UPPER(whsezone_name)=UPPER(pWhseZoneName)) );

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Whsezone % not found.', pWhseZoneName;
  END IF;

  RETURN _returnVal;
END;

Function: public.grantallmodulecmnttypesource(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmnttypeid ALIAS FOR $1;
  pModuleName ALIAS FOR $2;
  _source RECORD;
  _sourceCounter INTEGER;

BEGIN

  _sourceCounter := 0;

  FOR _source IN SELECT source_id
                 FROM source 
                 WHERE (source_module=pModuleName) LOOP

    IF (SELECT grantCmnttypeSource(pCmnttypeid, _source.source_id)) THEN
      _sourceCounter := _sourceCounter + 1;
    END IF;

  END LOOP;

  RETURN _sourceCounter;

END;

Function: public.grantallmodulepriv(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pModuleName ALIAS FOR $2;
  _priv RECORD;
  _privCounter INTEGER;

BEGIN

  _privCounter := 0;

  FOR _priv IN SELECT priv_id
               FROM priv 
               WHERE (priv_module=pModuleName) LOOP

    IF (SELECT grantPriv(pUsername, _priv.priv_id)) THEN
      _privCounter := _privCounter + 1;
    END IF;

  END LOOP;

  RETURN _privCounter;

END;

Function: public.grantallmoduleprivgroup(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGrpid ALIAS FOR $1;
  pModuleName ALIAS FOR $2;
  _priv RECORD;
  _privCounter INTEGER;

BEGIN

  _privCounter := 0;

  FOR _priv IN SELECT priv_id
               FROM priv 
               WHERE (priv_module=pModuleName) LOOP

    IF (SELECT grantPrivGroup(pGrpid, _priv.priv_id)) THEN
      _privCounter := _privCounter + 1;
    END IF;

  END LOOP;

  RETURN _privCounter;

END;

Function: public.grantcmnttypesource(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmnttypeid ALIAS FOR $1;
  pSourceid ALIAS FOR $2;
  _test INTEGER;

BEGIN

  SELECT cmnttypesource_id INTO _test
  FROM cmnttypesource
  WHERE ( (cmnttypesource_cmnttype_id=pCmnttypeid)
    AND (cmnttypesource_source_id=pSourceid) );

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

  INSERT INTO cmnttypesource
  ( cmnttypesource_cmnttype_id, cmnttypesource_source_id )
  VALUES
  ( pCmnttypeid, pSourceid );

  RETURN TRUE;

END;

Function: public.grantgroup(text, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pGrpid ALIAS FOR $2;
  _test INTEGER;

BEGIN

  SELECT usrgrp_id INTO _test
  FROM usrgrp
  WHERE ( (usrgrp_username=pUsername)
   AND (usrgrp_grp_id=pGrpid) );

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

  INSERT INTO usrgrp
  ( usrgrp_username, usrgrp_grp_id )
  VALUES
  ( pUsername, pGrpid );

  RETURN TRUE;

END;

Function: public.grantpriv(text, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrivid ALIAS FOR $2;
  _test INTEGER;

BEGIN

  SELECT usrpriv_id INTO _test
  FROM usrpriv
  WHERE ( (usrpriv_username=pUsername)
   AND (usrpriv_priv_id=pPrivid) );

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

  INSERT INTO usrpriv
  ( usrpriv_username, usrpriv_priv_id )
  VALUES
  ( pUsername, pPrivid );

  NOTIFY "usrprivUpdated";

  RETURN TRUE;

END;

Function: public.grantpriv(text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrivname ALIAS FOR $2;
  _test INTEGER;

BEGIN

  SELECT usrpriv_id INTO _test
    FROM usrpriv
    JOIN priv ON (usrpriv_priv_id=priv_id)
  WHERE ((usrpriv_username=pUsername)
     AND (priv_name=pPrivname) );

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

  INSERT INTO usrpriv
  ( usrpriv_username, usrpriv_priv_id )
  SELECT pUsername, priv_id
    FROM priv
   WHERE (priv_name=pPrivname);

  NOTIFY "usrprivUpdated";

  RETURN TRUE;

END;

Function: public.grantprivgroup(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGrpid ALIAS FOR $1;
  pPrivid ALIAS FOR $2;
  _test INTEGER;

BEGIN

  SELECT grppriv_id INTO _test
  FROM grppriv
  WHERE ( (grppriv_grp_id=pGrpid)
   AND (grppriv_priv_id=pPrivid) );

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

  INSERT INTO grppriv
  ( grppriv_grp_id, grppriv_priv_id )
  VALUES
  ( pGrpid, pPrivid );

  RETURN TRUE;

END;

Function: public.hasalarms()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _alarm          RECORD;
  _batchId        INTEGER;
  _evntlogordtype TEXT;
  _evnttypeid     INTEGER;
  _evnttypename   TEXT;
  _fromEmail      TEXT;
  _itemid         INTEGER;
  _longsource     TEXT;
  _msgId          INTEGER;
  _recipient      TEXT;
  _recipientPart  INTEGER;
  _returnVal      BOOLEAN := FALSE;
  _summary        TEXT;
  _whsId          INTEGER := -1;

BEGIN
  FOR _alarm IN SELECT *
                FROM alarm
                WHERE ((alarm_creator=getEffectiveXtUser())
                   AND (CURRENT_TIMESTAMP > alarm_trigger)) LOOP
    _returnVal := TRUE;

    IF (_alarm.alarm_source = 'TODO') THEN
      SELECT (todoitem_name || '-' || todoitem_description),
             'T', 'TodoAlarm', 'To-Do Item'
      INTO _summary, _evntlogordtype, _evnttypename, _longsource
      FROM todoitem
      WHERE (todoitem_id = _alarm.alarm_source_id);

    ELSIF (_alarm.alarm_source = 'INCDT') THEN
      SELECT (incdt_number || '-' || incdt_summary),
             'I', 'IncidentAlarm', 'Incident'
      INTO _summary, _evntlogordtype, _evnttypename, _longsource
      FROM incdt
      WHERE (incdt_id = _alarm.alarm_source_id);

    ELSIF (_alarm.alarm_source = 'J') THEN
      SELECT (prj_number || ' ' || prj_name || '-' || prjtask_name),
              'J', 'TaskAlarm', 'Project Task'
      INTO _summary, _evntlogordtype, _evnttypename, _longsource
      FROM prjtask JOIN prj ON (prj_id=prjtask_prj_id)
      WHERE (prjtask_id = _alarm.alarm_source_id);

    ELSE
      CONTINUE; -- there's nothing to do for this iteration of the loop
    END IF;

    -- if event alarm
    IF (_alarm.alarm_event) THEN
      SELECT evnttype_id INTO _evnttypeid
      FROM evnttype
      WHERE (evnttype_name=_evnttypename);

      _recipientPart := 1;
      LOOP
        _recipient := SPLIT_PART(_alarm.alarm_event_recipient, ',', _recipientPart);
        EXIT WHEN (LENGTH(_recipient) = 0);

        SELECT usrpref_value INTO _whsId
        FROM usrpref
        WHERE ( (usrpref_username = _recipient)
          AND   (usrpref_name = 'PreferredWarehouse') );

        INSERT INTO evntlog (evntlog_evnttime, evntlog_username,
                             evntlog_evnttype_id, evntlog_ordtype,
                             evntlog_ord_id, evntlog_warehous_id, evntlog_number
                   ) VALUES (CURRENT_TIMESTAMP, _recipient,
                             _evnttypeid, _evntlogordtype,
                             _alarm.alarm_source_id, _whsId, _summary);

        _recipientPart := _recipientPart + 1;
      END LOOP;
    END IF;

    IF (_alarm.alarm_email) THEN
      SELECT usr_email INTO _fromEmail
      FROM usr
      WHERE (usr_username = _alarm.alarm_creator);

      _recipientPart := 1;
      LOOP
        _recipient := SPLIT_PART(_alarm.alarm_email_recipient, ',', _recipientPart);
        EXIT WHEN (LENGTH(_recipient) <= 0);
        _batchId := xtbatch.submitEmailToBatch(_fromEmail, _recipient, '',
                                               _summary,
                                               'Alarm reminder for '
                                               || _longsource || '.',
                                               NULL, CURRENT_TIMESTAMP,
                                               FALSE, NULL, NULL);
        _recipientPart := _recipientPart + 1;
      END LOOP;
    END IF;

    IF (_alarm.alarm_sysmsg) THEN
      _recipientPart := 1;
      LOOP
        _recipient := SPLIT_PART(_alarm.alarm_sysmsg_recipient, ',', _recipientPart);
        EXIT WHEN (LENGTH(_recipient) <= 0);
        _msgId := postMessage(_recipient, (_longsource || ' - ' || _summary));
        _recipientPart := _recipientPart + 1;
      END LOOP;
    END IF;

    DELETE FROM alarm WHERE alarm_id=_alarm.alarm_id;
  END LOOP;
  RETURN _returnVal;

END;

Function: public.hasevents()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  PERFORM evntlog_id
  FROM evntlog
  WHERE ( (evntlog_dispatched IS NULL)
   AND (evntlog_username=getEffectiveXtUser()) )
  LIMIT 1;
  RETURN FOUND;

END;

Function: public.hasmessages()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  PERFORM msguser_id
  FROM msg, msguser
  WHERE ( (msguser_username=getEffectiveXtUser())
   AND (msguser_msg_id=msg_id)
   AND (CURRENT_TIMESTAMP BETWEEN msg_scheduled AND msg_expires)
   AND (msguser_viewed IS NULL) )
  LIMIT 1;
  RETURN FOUND;

END;

Function: public.haspriv(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrivName	ALIAS FOR $1;
  _result       INTEGER;
  _returnVal	BOOLEAN;

BEGIN
  RAISE NOTICE 'hasPriv(TEXT) is deprecated. Use checkPrivilege(TEXT) instead.';
  SELECT priv_id INTO _result
    FROM priv, grppriv, usrgrp
   WHERE((usrgrp_grp_id=grppriv_grp_id)
     AND (grppriv_priv_id=priv_id)
     AND (priv_name=pPrivName)
     AND (usrgrp_username=getEffectiveXtUser()));
  IF (FOUND) THEN
    RETURN true;
  END IF;

  SELECT COALESCE(usrpriv_id, 0) != 0 INTO _returnVal
  FROM priv LEFT OUTER JOIN
       usrpriv ON (priv_id=usrpriv_priv_id AND usrpriv_username = getEffectiveXtUser())
  WHERE (priv_name=pPrivName);
  IF (_returnVal IS NULL) THEN
    _returnVal := FALSE;
  END IF;

  RETURN _returnVal;
END;

Function: public.hasprivonobject(puser text, pobjectid text, pobjecttype integer, pprivtype text)

Returns: boolean

Language: PLPGSQL

Return if a user has permission to view or edit a specific database object. pPrivType is either CREATE, EDIT, DELETE, or VIEW, and controls which privilege is checked. pObjectType is one of the string constants used by the Documents widget, such as ADDR for Addresses. pObjectId is the internal id of the record in the table associated with pObjectType (defaults to NULL). pUser is the username to be checked for those pObjectTypes that restrict access to individual users (NULL == current user and is the default).

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _haspriv   BOOLEAN := FALSE;
  _privfound BOOLEAN := FALSE;
  _pkey      TEXT[];
  _privdesc  RECORD;
  _qstr      TEXT;

BEGIN
  IF UPPER(pPrivType) NOT IN ('CREATE', 'EDIT', 'VIEW', 'DELETE') THEN
    RAISE EXCEPTION 'Cannot check if user has % on % [xtuple: hasPrivOnObject, -1, %, %]',
                     pPrivType, pObjectType, pPrivType, pObjectType;
  END IF;

  /* TODO: create privdesc table? can't do it yet because this is a fix for a minor release
     NOTE: only include tables that have a single integer column as pkey
     NOTE: some of these are part of proprietary extensions. how do we make them part of the extension?
  */
  FOR _privdesc IN
  WITH privdesc AS (
    SELECT 'ADDR' AS otype,    'public' AS masterschema,
                                         'addr' AS mastertable,
                                                     'MaintainAddressMasters' AS editall,
                                                                                     'ViewAddressMasters' AS viewall,
                                                                                                               NULL AS ownerfield,        NULL AS editmine,                NULL AS viewmine
     UNION ALL SELECT 'BBH',   'xtmfg',  'bbom',     'MaintainBBOMs',                'ViewBBOMs',              NULL,                      NULL,                            NULL
     UNION ALL SELECT 'BBI',   'xtmfg',  'bbom',     'MaintainBBOMs',                'ViewBBOMs',              NULL,                      NULL,                            NULL
     UNION ALL SELECT 'BMH',   'public', 'bom',      'MaintainBOMs',                 'ViewBOMs',               NULL,                      NULL,                            NULL
     UNION ALL SELECT 'BMI',   'public', 'bom',      'MaintainBOMs',                 'ViewBOMs',               NULL,                      NULL,                            NULL
     UNION ALL SELECT 'BOH',   'xtmfg',  'boo',      'MaintainBOOs',                 'ViewBOOs',               NULL,                      NULL,                            NULL
     UNION ALL SELECT 'BOI',   'xtmfg',  'boo',      'MaintainBOOs',                 'ViewBOOs',               NULL,                      NULL,                            NULL
     UNION ALL SELECT 'C',     'public', 'custinfo', 'MaintainCustomerMasters',      'ViewCustomerMasters',    NULL,                      NULL,                            NULL
     UNION ALL SELECT 'CRMA',  'public', 'crmacct',  'MaintainAllCRMAccounts',       'ViewAllCRMAccounts',     'crmacct_owner_username',  'MaintainPersonalCRMAccounts',   'ViewPersonalCRMAccounts'
     UNION ALL SELECT 'EMP',   'public', 'emp',      'MaintainEmployees',            'ViewEmployees',          NULL,                      NULL,                            NULL
     UNION ALL SELECT 'I',     'public', 'item',     'MaintainItemMasters',          'ViewItemMasters',        NULL,                      NULL,                            NULL
     UNION ALL SELECT 'INCDT', 'public', 'incdt',    'MaintainAllIncidents',         'ViewAllIncidents',       'incdt_owner_username',    'MaintainPersonalIncidents',     'ViewPersonalIncidents'
     UNION ALL SELECT 'IR',    'public', 'itemsrc',  'MaintainItemSources',          'ViewItemSources',        NULL,                      NULL,                            NULL
     UNION ALL SELECT 'IS',    'public', 'itemsite', 'MaintainItemSites',            'ViewItemSites',          NULL,                      NULL,                            NULL
     UNION ALL SELECT 'J',     'public', 'prj',      'MaintainAllProjects',          'ViewAllProjects',        'prj_owner_username',      'MaintainPersonalProjects',      'ViewPersonalProjects'
     UNION ALL SELECT 'J',     'public', 'prj',      'MaintainAllProjects',          'ViewAllProjects',        'prj_username',            'MaintainPersonalProjects',      'ViewPersonalProjects'
     UNION ALL SELECT 'L',     'public', 'location', 'MaintainLocations',            'ViewLocations',          NULL,                      NULL,                            NULL
     UNION ALL SELECT 'OPP',   'public', 'ophead',   'MaintainAllOpportunities',     'ViewAllOpportunities',   'ophead_owner_username',   'MaintainPersonalOpportunities', 'ViewPersonalOpportunities'
     UNION ALL SELECT 'P',     'public', 'pohead',   'MaintainPurchaseOrders',       'ViewPurchaseOrders',     NULL,                      NULL,                            NULL
     UNION ALL SELECT 'PI',    'public', 'pohead',   'MaintainPurchaseOrders',       'ViewPurchaseOrders',     NULL,                      NULL,                            NULL
     UNION ALL SELECT 'Q',     'public', 'quhead',   'MaintainQuotes',               'ViewQuotes',             NULL,                      NULL,                            NULL
     UNION ALL SELECT 'QI',    'public', 'quhead',   'MaintainQuotes',               'ViewQuotes',             NULL,                      NULL,                            NULL
     UNION ALL SELECT 'RA',    'public', 'rahead',   'MaintainReturns',              'ViewReturns',            NULL,                      NULL,                            NULL
     UNION ALL SELECT 'RI',    'public', 'rahead',   'MaintainReturns',              'ViewReturns',            NULL,                      NULL,                            NULL
     UNION ALL SELECT 'S',     'public', 'cohead',   'MaintainSalesOrders',          'ViewSalesOrders',        NULL,                      NULL,                            NULL
     UNION ALL SELECT 'SI',    'public', 'cohead',   'MaintainSalesOrders',          'ViewSalesOrders',        NULL,                      NULL,                            NULL
     UNION ALL SELECT 'T',     'public', 'cntct',    'MaintainAllContacts',          'ViewAllContacts',        'cntct_owner_username',    'MaintainPersonalContacts',      'ViewPersonalContacts'
     UNION ALL SELECT 'TE',    'te',     'tehead',   'MaintainTimeExpense',          'ViewTimeExpenseHistory', 'tehead_username',         'MaintainTimeExpenseSelf',       NULL
     UNION ALL SELECT 'TE',    'te',     'tehead',   'MaintainTimeExpenseOthers',    'ViewTimeExpenseHistory', 'tehead_username',         'MaintainTimeExpenseSelf',       NULL
     UNION ALL SELECT 'TI',    'public', 'tohead',   'MaintainTransferOrders',       'ViewTransferOrders',     NULL,                      NULL,                            NULL
     UNION ALL SELECT 'TO',    'public', 'tohead',   'MaintainTransferOrders',       'ViewTransferOrders',     NULL,                      NULL,                            NULL
     UNION ALL SELECT 'TODO',  'public', 'todoitem', 'MaintainAllToDoItems',         'ViewAllToDoItems',       'todoitem_owner_username', 'MaintainPersonalToDoItems',     'ViewPersonalToDoItems'
     UNION ALL SELECT 'V',     'public', 'vendinfo', 'MaintainVendors',              'ViewVendors',            NULL,                      NULL,                            NULL
     UNION ALL SELECT 'W',     'public', 'wo',       'MaintainWorkOrders',           'ViewWorkOrders',         NULL,                      NULL,                            NULL
     UNION ALL SELECT 'WH',    'public', 'whsinfo',  'MaintainWarehouses',           'ViewWarehouses',         NULL,                      NULL,                            NULL)
  -- UNION ALL SELECT 'LS',    'public', 'ls',       NULL,                           NULL,                     NULL,                      NULL,                            NULL
  -- UNION ALL SELECT 'P',     'public', 'pohead',   'MaintainPostedPurchaseOrders', 'ViewPurchaseOrders',     NULL,                      NULL,                            NULL -- additional criteria?
  -- UNION ALL SELECT 'PI',    'public', 'pohead',   'MaintainPostedPurchaseOrders', 'ViewPurchaseOrders',     NULL,                      NULL,                            NULL -- additional criteria?
     SELECT *
       FROM privdesc
      WHERE otype = pObjectType
  LOOP
    _privfound := TRUE;
    RAISE DEBUG '% % % % % % %',
                _privdesc.otype, _privdesc.masterschema, _privdesc.mastertable,
                _privdesc.editall, _privdesc.viewall, _privdesc.editmine, _privdesc.viewmine;

    IF checkPrivilege(CASE UPPER(pPrivType) WHEN 'CREATE' THEN _privdesc.editall
                                            WHEN 'EDIT'   THEN _privdesc.editall
                                            WHEN 'DELETE' THEN _privdesc.editall
                                            WHEN 'VIEW'   THEN _privdesc.viewall
                      END) THEN
      _haspriv = TRUE;

    ELSIF checkPrivilege(CASE UPPER(pPrivType) WHEN 'CREATE' THEN _privdesc.editmine
                                               WHEN 'EDIT'   THEN _privdesc.editmine
                                               WHEN 'DELETE' THEN _privdesc.editmine
                                               WHEN 'VIEW'   THEN _privdesc.viewmine
                         END) THEN
      IF pObjectId IS NULL THEN
      _haspriv = TRUE;

      ELSE
        _pkey := primaryKeyFields(_privdesc.masterschema, _privdesc.mastertable);

        -- SELECT ... FROM schema.table WHERE pkeyfield = pObjectId AND ownerfield = pUser
        _qstr := 'SELECT EXISTS(SELECT 1
                                  FROM ' || quote_ident(_privdesc.masterschema)
                                   || '.' || quote_ident(_privdesc.mastertable)
                                   || ' WHERE ' || quote_ident(_pkey[1]) || ' = ' || pObjectId
                                   || '   AND ' || quote_ident(_privdesc.ownerfield)
                                   || '= ' || quote_literal(COALESCE(pUser, getEffectiveXtUser())) || ');';
        RAISE DEBUG '%', _qstr;

        EXECUTE _qstr INTO _haspriv;
      END IF;
    END IF;

    EXIT WHEN _haspriv;
  END LOOP;

  RETURN _haspriv OR NOT _privfound;

END;

Function: public.hmac(bytea, bytea, text)

Returns: bytea

Language: C

pg_hmac

Function: public.hmac(text, text, text)

Returns: bytea

Language: C

pg_hmac

Function: public.implodewo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  implodeChildren ALIAS FOR $2;
  resultCode INTEGER;
  _wotcCnt   INTEGER;
  _routings  BOOLEAN;

BEGIN
  SELECT metric_value='t' INTO _routings
         FROM metric
         WHERE (metric_name='Routings');

  IF ((SELECT wo_id
       FROM wo
       WHERE ((wo_status='E')
        AND (wo_id=pWoid))) IS NULL) THEN
    RETURN 0;
  END IF;

  IF (_routings) THEN
    SELECT count(*) INTO _wotcCnt
    FROM xtmfg.wotc
    WHERE (wotc_wo_id=pWoid);
    IF (_wotcCnt > 0) THEN
      RETURN -1;
    END IF;
  END IF;

--  Delete any created P/R's for this W/O
  PERFORM deletePr('W', womatl_id)
  FROM womatl
  WHERE (womatl_wo_id=pWoid);

  DELETE FROM womatl
  WHERE (womatl_id IN ( SELECT womatl_id
                        FROM womatl, wo
                        WHERE ((womatl_wo_id=wo_id)
                         AND (wo_status='E')
                         AND (wo_id=pWoid)) ));

  IF _routings THEN

    DELETE FROM xtmfg.wooper
    WHERE (wooper_id IN ( SELECT wooper_id
                          FROM xtmfg.wooper, wo
                          WHERE ((wooper_wo_id=wo_id)
                           AND (wo_status='E')
                           AND (wo_id=pWoid)) ));
  END IF;

  UPDATE wo
  SET wo_status='O'
  WHERE (wo_id=pWoid);

  IF (implodeChildren) THEN
    resultCode := (SELECT MAX(implodeWo(wo_id, TRUE))
                   FROM wo
                   WHERE ((wo_ordtype='W')
                    AND (wo_ordid=pWoid)));

    resultCode := (SELECT MAX(deleteWo(wo_id, TRUE))
                   FROM wo
                   WHERE ((wo_ordtype='W')
                    AND (wo_ordid=pWoid)));
  END IF;

  RETURN 0;
END;

Function: public.incdt()

Returns: SET OF incdt

Language: PLPGSQL

A table function that returns Incident results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row incdt%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllIncidents','ViewAllIncidents','MaintainPersonalIncidents','ViewPersonalIncidents')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM incdt
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM incdt 
      WHERE  getEffectiveXtUser() IN (incdt_owner_username, incdt_assigned_username)
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.indentedbom(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _revid INTEGER;

BEGIN

  SELECT getActiveRevId('BOM',pItemid) INTO _revid;

  RETURN indentedBOM(pItemid, _revid);

END;

Function: public.indentedbom(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  _bomworkid INTEGER;
  _indexid INTEGER;
  _r RECORD;

BEGIN

--  Check on the temporary workspace
--  PERFORM maintainBOMWorkspace();

--  Grab a new index for this bomwork set
  SELECT NEXTVAL('misc_index_seq') INTO _indexid;

--  Step through all of the components of the passed pItemid
  FOR _r IN SELECT bomitem.*,
                   item_id,
                   (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL)
                               * bomitem_qtyfxd) AS qtyfxd,
                   (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL)
                               * bomitem_qtyper) AS qtyper,
                   stdcost(item_id, bomitem_id) AS standardcost,
                   actcost(item_id, bomitem_id) AS actualcost
  FROM bomitem(pItemId, pRevisionid), item
  WHERE ( (bomitem_item_id=item_id) ) LOOP

--  Insert the component and bomitem parameters
    SELECT NEXTVAL('bomwork_bomwork_id_seq') INTO _bomworkid;
    INSERT INTO bomwork
    ( bomwork_id, bomwork_set_id, bomwork_parent_id, bomwork_level,
      bomwork_parent_seqnumber, bomwork_seqnumber,
      bomwork_item_id, bomwork_createwo, bomwork_qtyreq,
      bomwork_qtyfxd, bomwork_qtyper, bomwork_scrap, bomwork_issuemethod,
      bomwork_effective, bomwork_expires,
      bomwork_stdunitcost, bomwork_actunitcost,
      bomwork_char_id, bomwork_value, bomwork_notes, bomwork_ref,
      bomwork_bomitem_id, bomwork_ecn )
    VALUES
    ( _bomworkid, _indexid, -1, 1,
      0, _r.bomitem_seqnumber,
      _r.item_id, _r.bomitem_createwo, (_r.qtyfxd + _r.qtyper),
      _r.qtyfxd, _r.qtyper, _r.bomitem_scrap, _r.bomitem_issuemethod,
      _r.bomitem_effective, _r.bomitem_expires,
      _r.standardcost, _r.actualcost,
      _r.bomitem_char_id, _r.bomitem_value, _r.bomitem_notes, _r.bomitem_ref,
      _r.bomitem_id, _r.bomitem_ecn );

--  Explode the components of the current component
    PERFORM explodeBOM(_r.item_id, _bomworkid, 1);

  END LOOP;

--  Return a key to the result
  RETURN _indexid;

END;

Function: public.indentedbom(integer, integer, integer, integer)

Returns: SET OF bomdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  pExpiredDays ALIAS FOR $3;
  pFutureDays ALIAS FOR $4;
  _row bomdata%ROWTYPE;
  _bomworksetid INTEGER;
  _x RECORD;
  _check CHAR(1);
  _inactive BOOLEAN := FALSE;
  _batchsize NUMERIC;
BEGIN

  IF (pRevisionid != -1) THEN
    --Is this a deactivated revision?
    SELECT rev_status INTO _check
    FROM rev
    WHERE ((rev_id=pRevisionid)
    AND (rev_status='I'));
    IF (FOUND) THEN
      _inactive := TRUE;
    END IF;
  END IF;
 
  -- Get the batch quantity
  SELECT COALESCE( (
    SELECT bomhead_batchsize
    FROM bomhead
    WHERE ((bomhead_item_id=pItemId)
    AND (bomhead_rev_id=pRevisionid)) LIMIT 1),1) INTO _batchsize;
 
  IF NOT (_inactive) THEN

    --We can explode this out based on current data
    SELECT indentedBOM(pItemid, pRevisionid) INTO _bomworksetid;  

    FOR _x IN
        SELECT bomwork_id, bomwork_parent_id, bomwork_level,
               bomworkSequence(bomwork_id) AS seq_ord,
               bomwork_seqnumber, item_id, item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               bomwork_qtyreq, bomwork_qtyfxd, bomwork_qtyper, bomwork_scrap, bomwork_createwo,
       CASE WHEN (bomwork_issuemethod='S') THEN 'Push'
            WHEN (bomwork_issuemethod='L') THEN 'Pull'
            WHEN (bomwork_issuemethod='M') THEN 'Mixed'
            ELSE 'Special'
       END AS issuemethod,
       bomwork_effective, bomwork_expires,
       (bomwork_expires <= CURRENT_DATE) AS expired,
       (bomwork_effective > CURRENT_DATE) AS future,
       bomwork_actunitcost AS actunitcost,
       bomwork_stdunitcost AS stdunitcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         itemuomtouomratio(item_id, item_inv_uom_id, NULL) * (bomwork_qtyfxd/_batchsize + bomwork_qtyper) * (1 + bomwork_scrap) * bomwork_actunitcost
       ELSE 0 END AS actextendedcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         itemuomtouomratio(item_id, item_inv_uom_id, NULL) * (bomwork_qtyfxd/_batchsize + bomwork_qtyper) * (1 + bomwork_scrap) * bomwork_stdunitcost
       ELSE 0 END AS stdextendedcost,
       bomwork_char_id,
       bomwork_value, bomwork_notes, bomwork_ref,
       bomwork_bomitem_id, bomwork_ecn
       FROM bomwork, item, uom 
       WHERE ( (bomwork_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (bomwork_set_id=_bomworksetid) )
       AND (bomwork_expires > (CURRENT_DATE - pExpiredDays))
       AND (bomwork_effective <= (CURRENT_DATE + pFutureDays))
       UNION
       SELECT -1, -1, 1,
              '0',
              NULL,-1, costelem_type AS bomdata_item_number, '',
              '', '',
              '',
              NULL, NULL, NULL, NULL, NULL,
              '',
              NULL, NULL,
              false,
              false,
              currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) AS actunitcost,
              itemcost_stdcost AS stdunitcost,
              currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) AS actextendedcost,
              itemcost_stdcost AS stdextendedcost,
              NULL,
              NULL,NULL,NULL,
              NULL,NULL
       FROM itemcost, costelem 
       WHERE ( (itemcost_costelem_id=costelem_id)
       AND (NOT itemcost_lowlevel)
       AND (itemcost_item_id=pItemid) )
       ORDER BY seq_ord
    LOOP
        _row.bomdata_bomwork_id := _x.bomwork_id;
        _row.bomdata_bomwork_parent_id := _x.bomwork_parent_id;
        _row.bomdata_bomwork_level := _x.bomwork_level;
        _row.bomdata_bomwork_seqnumber := _x.bomwork_seqnumber;
        _row.bomdata_bomitem_id := _x.bomwork_bomitem_id;
        _row.bomdata_item_id := _x.item_id;
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_batchsize := _batchsize;
        _row.bomdata_qtyreq := _x.bomwork_qtyreq;
        _row.bomdata_qtyfxd := _x.bomwork_qtyfxd;
        _row.bomdata_qtyper := _x.bomwork_qtyper;
        _row.bomdata_scrap := _x.bomwork_scrap;
        _row.bomdata_createchild := _x.bomwork_createwo;
        _row.bomdata_issuemethod := _x.issuemethod;
        _row.bomdata_effective := _x.bomwork_effective;
        _row.bomdata_expires := _x.bomwork_expires;
        _row.bomdata_expired := _x.expired;
        _row.bomdata_future := _x.future;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        _row.bomdata_ecn := _x.bomwork_ecn;
        _row.bomdata_char_id := _x.bomwork_char_id;
        _row.bomdata_value := _x.bomwork_value;
        _row.bomdata_notes := _x.bomwork_notes;
        _row.bomdata_ref := _x.bomwork_ref;
        RETURN NEXT _row;
    END LOOP;
    
    PERFORM deleteBOMWorkset(_bomworksetid);

  ELSE

-- Use historical snapshot for inactive revisions
    FOR _x IN
        SELECT bomhist_id, bomhist_parent_id, bomhist_level,
               bomhistSequence(bomhist_seq_id) AS seq_ord,
               bomhist_seqnumber, item_id, item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               bomhist_qtyreq, bomhist_qtyfxd, bomhist_qtyper, bomhist_scrap,
               bomhist_createwo,
       CASE WHEN (bomhist_issuemethod='S') THEN 'Push'
            WHEN (bomhist_issuemethod='L') THEN 'Pull'
            WHEN (bomhist_issuemethod='M') THEN 'Mixed'
            ELSE 'Special'
       END AS issuemethod,
       bomhist_effective, bomhist_expires,
       (bomhist_expires <= CURRENT_DATE) AS expired,
       (bomhist_effective > CURRENT_DATE) AS future,
       bomhist_actunitcost AS actunitcost,
       bomhist_stdunitcost AS stdunitcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         (bomist_qtyfxd/_batchsize + bomhist_qtyper) * (1 + bomhist_scrap) * bomhist_actunitcost
       ELSE 0 END AS actextendedcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         (bomist_qtyfxd/_batchsize + bomhist_qtyper) * (1 + bomhist_scrap) * bomhist_stdunitcost
       ELSE 0 END AS stdextendedcost,
       bomhist_char_id, bomhist_value, bomhist_notes, bomhist_ref 
       FROM bomhist, item, uom 
       WHERE ( (bomhist_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (bomhist_rev_id=pRevisionid) )
       AND (bomhist_expires > (CURRENT_DATE - pExpiredDays))
       AND (bomhist_effective <= (CURRENT_DATE + pFutureDays))
       UNION
       SELECT -1, -1, 1,
              '0',
              NULL,-1, costelem_type AS bomdata_item_number, '',
              '', '',
              '',
              NULL, NULL, NULL, NULL,
              false,
              '', NULL, NULL,
              false,
              false,
              bomhist_actunitcost AS actunitcost,
              bomhist_stdunitcost AS stdunitcost,
              bomhist_actunitcost AS actextendedcost,
              bomhist_stdunitcost AS stdextendedcost,
              NULL,NULL,NULL,NULL 
       FROM bomhist, costelem 
       WHERE ((bomhist_rev_id=pRevisionid)
       AND (costelem_id=bomhist_item_id))
       ORDER BY seq_ord
    LOOP
        _row.bomdata_bomwork_id := _x.bomhist_id;
        _row.bomdata_bomwork_parent_id := _x.bomhist_parent_id;
        _row.bomdata_bomwork_level := _x.bomhist_level;
        _row.bomdata_bomwork_seqnumber := _x.bomhist_seqnumber;
        _row.bomdata_bomitem_id := -1;
        _row.bomdata_item_id := _x.item_id;
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_batchsize := _batchsize;
        _row.bomdata_qtyreq := _x.bomhist_qtyreq;
        _row.bomdata_qtyfxd := _x.bomist_qtyfxd;
        _row.bomdata_qtyper := _x.bomhist_qtyper;
        _row.bomdata_scrap := _x.bomhist_scrap;
        _row.bomdata_createchild := _x.bomhist_createwo;
        _row.bomdata_issuemethod := _x.issuemethod;
        _row.bomdata_effective := _x.bomhist_effective;
        _row.bomdata_expires := _x.bomhist_expires;
        _row.bomdata_expired := _x.expired;
        _row.bomdata_future := _x.future;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        _row.bomdata_ecn := '';
        _row.bomdata_char_id := _x.bomhist_char_id;
        _row.bomdata_value := _x.bomhist_value;
        _row.bomdata_notes := _x.bomhist_notes;
        _row.bomdata_ref := _x.bomhist_ref;
        RETURN NEXT _row;
    END LOOP;
  END IF;   

  RETURN;
END;

Function: public.indentedwhereused(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _indexid INTEGER;
  _level INTEGER;

BEGIN

--  Check on the temporary workspace
--  PERFORM maintainBOMWorkspace();

  _indexid := (SELECT NEXTVAL('misc_index_seq'));
  _level := 1;

  INSERT INTO bomwork
  ( bomwork_set_id, bomwork_parent_id,
    bomwork_level, bomwork_seqnumber,
    bomwork_item_id, bomwork_item_type, bomwork_createwo,
    bomwork_qtyfxd, bomwork_qtyper,
    bomwork_scrap, bomwork_issuemethod,
    bomwork_effective, bomwork_expires, bomwork_status,
    bomwork_stdunitcost, bomwork_actunitcost )
  SELECT _indexid, -1,
         1, bomitem_seqnumber,
         item_id, item_type, bomitem_createwo,
         (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyfxd),
         (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyper),
         bomitem_scrap, bomitem_issuemethod,
         bomitem_effective, bomitem_expires, 'U',
         stdcost(item_id), actcost(item_id)
  FROM bomitem, item
  WHERE ((bomitem_item_id=pItemid)
    AND (bomitem_parent_item_id=item_id)
    AND (CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1))
    AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id)));

  WHILE ( ( SELECT count(*)
            FROM bomwork
            WHERE ((bomwork_item_type IN ('M', 'F'))
              AND (bomwork_status='U')
              AND (bomwork_set_id=_indexid)) ) > 0) LOOP

    _level := _level + 1;

    INSERT INTO bomwork
    ( bomwork_set_id, bomwork_parent_id,
      bomwork_level, bomwork_seqnumber,
      bomwork_item_id, bomwork_item_type, bomwork_createwo,
      bomwork_qtyfxd, bomwork_qtyper,
      bomwork_scrap, bomwork_issuemethod,
      bomwork_effective, bomwork_expires, bomwork_status,
      bomwork_stdunitcost, bomwork_actunitcost )
    SELECT _indexid, bomwork_id,
           _level, bomitem_seqnumber,
           item_id, item_type, bomitem_createwo,
           (bomwork_qtyper * (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyfxd)),
           (bomwork_qtyper * (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyper)),
           bomitem_scrap, bomitem_issuemethod,
           CASE WHEN bomitem_effective < bomwork_effective THEN
             bomwork_effective
           ELSE bomitem_effective END, 
           CASE WHEN bomitem_expires > bomwork_expires THEN
             bomwork_expires
           ELSE bomitem_expires END,
           'N',
           stdcost(item_id), actcost(item_id)
    FROM bomwork JOIN bomitem ON ( (bomitem_item_id=bomwork_item_id)
                               AND (CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1))
                               AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id)) )
                 JOIN item ON (item_id=bomitem_parent_item_id)
    WHERE ((bomwork_status='U')
      AND  (bomwork_item_type IN ('M', 'F')));

    UPDATE bomwork
    SET bomwork_status='C'
    WHERE ((bomwork_status='U')
      AND (bomwork_set_id=_indexid));

    UPDATE bomwork
    SET bomwork_status='U'
    WHERE ((bomwork_status='N')
      AND (bomwork_set_id=_indexid));

  END LOOP;

  RETURN _indexid;
END;

Function: public.indentedwo(integer, boolean, boolean, boolean)

Returns: SET OF wodata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;
   pshowops ALIAS FOR $2;
   pshowmatl ALIAS FOR $3; 
   pshowindent ALIAS FOR $4;   
  _row wodata%ROWTYPE;
  _subrow wodata%ROWTYPE;  
  _opx wodata%ROWTYPE;
  _x RECORD;
  _level INTEGER;
   
BEGIN 
    --The wodata_id_type column is used to indicate the source of the wodata_id
    --there are three different tables used wo, womatl and womatlvar
    --wodata_id_type = 1 = wo_id
    --wodata_id_type = 2 = womatl_id
    --wodata_id_type = 3 = wooper_id
    --initialise values
    _level := 0;   
    --get top level works orders
    FOR _x IN
       SELECT wo_id,wo_number,wo_subnumber,wo_status,wo_startdate,
         wo_duedate,wo_adhoc,wo_itemsite_id,itemsite_qtyonhand,
         wo_qtyord,wo_qtyrcv,wo_prodnotes, item_number,
         item_descrip1, item_descrip2, uom_name
       FROM wo, itemsite, item, uom     
       WHERE ((wo_id = pwoid)
         AND (itemsite_id = wo_itemsite_id)
         AND (itemsite_item_id=item_id)
         AND (item_inv_uom_id=uom_id))      
       ORDER BY wo_number, wo_subnumber
    LOOP
        _row.wodata_id := _x.wo_id;
        _row.wodata_id_type := 1;            
        _row.wodata_number := _x.wo_number;
        _row.wodata_subnumber := _x.wo_subnumber;
        _row.wodata_itemnumber := _x.item_number;
        _row.wodata_descrip := _x.item_descrip1 || '-' || _x.item_descrip2;
        _row.wodata_status := _x.wo_status;
        _row.wodata_startdate := _x.wo_startdate;
        _row.wodata_duedate := _x.wo_duedate;
        _row.wodata_adhoc := _x.wo_adhoc;     
        _row.wodata_itemsite_id := _x.wo_itemsite_id;         
        _row.wodata_qoh := _x.itemsite_qtyonhand;
        _row.wodata_short := noneg(_x.wo_qtyord - _x.wo_qtyrcv);
        _row.wodata_qtyrcv := _x.wo_qtyrcv;   
        _row.wodata_qtyordreq := _x.wo_qtyord;   
        _row.wodata_qtyuom := _x.uom_name;    
        _row.wodata_scrap := 0;        
        _row.wodata_notes := _x.wo_prodnotes;     
        _row.wodata_level := _level;                
        RETURN NEXT _row;
        IF (pshowmatl AND NOT pshowops) THEN
          --expand materials      
          FOR _subrow IN
             SELECT * FROM indentedwomatl(pwoid, _level)
          LOOP                                                  
            RETURN NEXT _subrow;
          END LOOP;
        END IF;
        
        IF ((pshowmatl OR pshowindent) AND NOT pshowops) THEN
          --expand next level down               
          FOR _subrow IN
           SELECT * FROM indentedwo(_x.wo_id, NULL, _level + 1, pshowmatl, pshowindent) 
          LOOP                                           
            RETURN NEXT _subrow; 
          END LOOP;
        END IF;
          
        IF (pshowops) THEN
         --expand materials not on operations   
         IF (pshowmatl) THEN   
           FOR _subrow IN
             SELECT * FROM indentedwomatl(pwoid, -1, _level)
           LOOP                                                  
             RETURN NEXT _subrow;
           END LOOP;
         END IF;

         IF (pshowmatl OR pshowindent) THEN
           --expand next level down             
           FOR _subrow IN
             SELECT * FROM indentedwo(_x.wo_id, -1, _level + 1,  pshowmatl, pshowindent) 
           LOOP                                           
             RETURN NEXT _subrow; 
           END LOOP;
         END IF;

         --expand opeartions
         FOR _opx IN
           SELECT * FROM xtmfg.indentedwoops(pwoid,_level)
         LOOP
           RETURN NEXT _opx;

           IF (pshowmatl) THEN  
              --expand materials on operations      
              FOR _subrow IN
                 SELECT * FROM indentedwomatl(pwoid, _opx.wodata_id, _level + 1)
              LOOP                                                  
                RETURN NEXT _subrow;
              END LOOP;
           END IF;

           IF (pshowmatl OR pshowindent) THEN
              --expand next level down             
              FOR _subrow IN
                SELECT * FROM indentedwo(_x.wo_id, _opx.wodata_id, _level + 2,  pshowmatl, pshowindent) 
              LOOP                                           
                RETURN NEXT _subrow; 
              END LOOP;
           END IF; 
         END LOOP; 
       END IF;                           
  END LOOP;                     
  RETURN;
END;

Function: public.indentedwo(integer, integer, integer, boolean, boolean)

Returns: SET OF wodata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;   
   pwooperid ALIAS FOR $2;
   plevel ALIAS FOR $3;
   pshowmatl ALIAS FOR $4; 
   pshowindent ALIAS FOR $5;  
  _row wodata%ROWTYPE;   
  _opx wodata%ROWTYPE; 
  _x RECORD;
  _subx RECORD;
  _index INTEGER;
  _level INTEGER;
  _qry TEXT;
   
BEGIN 
    --The wodata id column is used to indicate the source of the id
    --there are three different tables used wo, womatl and womatlvar
    --wodata_id_type = 1 = wo_id
    --wodata_id_type = 2 = womatl_id
    --wodata_id_type = 3 = wooper_id
    _level := (plevel + 1);    
    --find all WO with the ordid of the next level up
    _qry := 'SELECT wo_id,wo_number,wo_subnumber,wo_status,wo_startdate,wo_duedate,
         wo_adhoc,wo_itemsite_id,itemsite_qtyonhand,wo_qtyord,wo_qtyrcv, wo_prodnotes,
         item_number,item_descrip1, item_descrip2, uom_name,
         womatl_qtyiss, womatl_scrap, womatl_wooper_id
       FROM itemsite,  wo, item, uom, womatl 
       WHERE ((wo_ordid = ' || pwoid || ')
         AND (wo_ordtype = ''W'')
         AND (itemsite_item_id=item_id)
         AND (item_inv_uom_id=uom_id)   
         AND (wo_womatl_id=womatl_id)   
         AND (wo_itemsite_id = itemsite_id) ';

    IF (pwooperid IS NOT NULL) THEN
      _qry := _qry || ' AND (womatl_wooper_id=' || pwooperid || ') ';
    END IF;               

    _qry := _qry || ') ORDER BY wo_number, wo_subnumber';
 /* if (pwooperid IS NOT NULL) THEN
    raise exception 'stop %',_qry;
  END IF;*/
    FOR _x IN
      EXECUTE _qry
    LOOP 
        _row.wodata_id := _x.wo_id;
        _row.wodata_id_type := 1;                     
        _row.wodata_number := _x.wo_number;
        _row.wodata_subnumber := _x.wo_subnumber;
        _row.wodata_itemnumber := _x.item_number;
        _row.wodata_descrip := _x.item_descrip1 || '-' || _x.item_descrip2;
        _row.wodata_status := _x.wo_status;
        _row.wodata_startdate := _x.wo_startdate;
        _row.wodata_duedate := _x.wo_duedate;
        _row.wodata_adhoc := _x.wo_adhoc;      
        _row.wodata_itemsite_id := _x.wo_itemsite_id;        
        _row.wodata_qoh := _x.itemsite_qtyonhand;
        _row.wodata_short := noneg(_x.wo_qtyord - _x.wo_qtyrcv);
        _row.wodata_qtyiss := _x.womatl_qtyiss;  
        _row.wodata_qtyrcv := _x.wo_qtyrcv;   
        _row.wodata_qtyordreq := _x.wo_qtyord; 
	_row.wodata_scrap := _x.womatl_scrap;  
        _row.wodata_notes := _x.wo_prodnotes;       
        _row.wodata_level := plevel;                
        RETURN NEXT _row;  
        --if indentation require expand next level
        IF (pshowindent AND pwooperid IS NULL) THEN
          IF (pshowmatl AND pshowindent) THEN    
      	    --get materials for this level
            FOR _subx IN
              SELECT * FROM indentedwomatl(_x.wo_id, plevel) 
	    LOOP                                            
	      RETURN NEXT _subx;
  	    END LOOP;
          END IF;

          IF (pshowindent) THEN  
            --expand lower levels 
            FOR _subx IN
              SELECT * FROM indentedwo(_x.wo_id, NULL, _level, pshowmatl, pshowindent )
            LOOP                                           
	      RETURN NEXT _subx; 
            END LOOP; 
          END IF;    
            
        ELSIF (pshowindent) THEN --Handle operations
          --expand materials not on operations   
          IF (pshowmatl) THEN   
            FOR _subx IN
              SELECT * FROM indentedwomatl(_x.wo_id, -1, plevel)
            LOOP                                                  
              RETURN NEXT _subx;
            END LOOP;
          END IF;

          --expand next level down not on operations
          FOR _subx IN
            SELECT * FROM indentedwo(_x.wo_id, -1, _level,  pshowmatl, pshowindent) 
          LOOP                                           
            RETURN NEXT _subx; 
          END LOOP;
          
          --expand operations
          FOR _opx IN
            SELECT * FROM xtmfg.indentedwoops(_x.wo_id,plevel)
          LOOP
            RETURN NEXT _opx;

            IF (pshowmatl) THEN  
              --expand materials on operations      
              FOR _subx IN
                 SELECT * FROM indentedwomatl(_x.wo_id, _opx.wodata_id, _level)
              LOOP                                                  
                RETURN NEXT _subx;
                --	raise exception 'stop %',_opx.wodata_id;
              END LOOP;
            END IF;
              
            --expand next level down   
            FOR _subx IN
              SELECT * FROM indentedwo(_x.wo_id, _opx.wodata_id, _level + 2,  pshowmatl, pshowindent) 
            LOOP                                        
              RETURN NEXT _subx; 
            END LOOP;
              
          END LOOP;
        END IF;      	              
      END LOOP;                         
  RETURN;
END;

Function: public.indentedwomatl(integer, integer)

Returns: SET OF wodata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;   
   plevel ALIAS FOR $2;
  _subx RECORD;
   
BEGIN
  FOR _subx IN
    SELECT * FROM indentedwomatl(pwoid, NULL::integer, plevel)
  LOOP
    RETURN NEXT _subx;
  END LOOP;        
  RETURN;
END;

Function: public.indentedwomatl(integer, integer, integer)

Returns: SET OF wodata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;  
   pwooperid ALIAS FOR $2; 
   plevel ALIAS FOR $3;
  _status TEXT; 
  _subrow wodata%ROWTYPE;  
  _subx RECORD;
  _level INTEGER;
  _qry TEXT;
   
BEGIN
  --The wodata id column is used to indicate the source of the id
  --there are three different tables used wo, womatl and womatlvar
  --wodata_id_type = 1 = wo_id
  --wodata_id_type = 2 = womatl_id
  --wodata_id_type = 3 = wooper_id

  _qry := 'SELECT womatl_id, wo_number, wo_subnumber, 
      wo_startdate, womatl_duedate, womatl_itemsite_id,
      itemsite_qtyonhand, womatl_qtyreq, womatl_qtyiss,
      womatl_qtyper, womatl_qtyreq, womatl_scrap,
      womatl_ref, womatl_notes, item_number,
      item_descrip1, item_descrip2, uom_name
    FROM womatl, wo, itemsite, item, uom
    WHERE ((wo_id = womatl_wo_id)
     AND (wo_id = ' || pwoid || ')
     AND (womatl_itemsite_id = itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (womatl_uom_id=uom_id) ';
-- Need to display in case child w/o is deleted
--     AND (NOT womatl_createwo OR womatl_createwo IS NULL) ';

  IF (pwooperid IS NOT NULL) THEN
    _qry := _qry || 'AND (womatl_wooper_id=' || pwooperid  || ')';
  END IF;

  _qry := _qry || ') ORDER BY item_number;';
  
  _level := plevel + 1;    
  SELECT wo_status FROM wo WHERE wo_id = pwoid  LIMIT 1 INTO _status;
 
  FOR _subx IN
    EXECUTE _qry
  LOOP
    _subrow.wodata_id := _subx.womatl_id;
    _subrow.wodata_id_type  := 2;       
    _subrow.wodata_number := _subx.wo_number;
    _subrow.wodata_subnumber := _subx.wo_subnumber;
    _subrow.wodata_itemnumber := _subx.item_number;
    _subrow.wodata_descrip := _subx.item_descrip1 || '-' || _subx.item_descrip2;
    _subrow.wodata_status := _status;
    _subrow.wodata_startdate := _subx.wo_startdate;
    _subrow.wodata_duedate := _subx.womatl_duedate;
    _subrow.wodata_itemsite_id := _subx.womatl_itemsite_id;    
    _subrow.wodata_qoh := _subx.itemsite_qtyonhand;
    IF((_subx.itemsite_qtyonhand > (_subx.womatl_qtyreq - _subx.womatl_qtyiss))) THEN
      _subrow.wodata_short := 0;
    ELSE
      _subrow.wodata_short := (_subx.womatl_qtyreq - _subx.womatl_qtyiss) -  _subx.itemsite_qtyonhand;
    END IF;
    _subrow.wodata_qtyper := _subx.womatl_qtyper;
    _subrow.wodata_qtyiss := _subx.womatl_qtyiss;         
    _subrow.wodata_qtyordreq := _subx.womatl_qtyreq;     
    _subrow.wodata_qtyuom := _subx.uom_name;   
    _subrow.wodata_scrap := _subx.womatl_scrap;        
    _subrow.wodata_notes := _subx.womatl_notes;
    _subrow.wodata_ref := _subx.womatl_ref;       
    _subrow.wodata_level := _level;                                   
    RETURN NEXT _subrow; 
  END LOOP;     
        
  RETURN;
END;

Function: public.initeffectivextuser()

Returns: void

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  -- Effective users use a temporary table to store the user information
  -- and this function, called by the other functions, makes sure the temp
  -- tables exist first.
  PERFORM *
     FROM pg_catalog.pg_class
    WHERE relname = 'effective_user'
      AND relnamespace = pg_catalog.pg_my_temp_schema();

  IF NOT FOUND THEN
    CREATE TEMPORARY TABLE effective_user (
      effective_key TEXT,
      effective_value TEXT
    );
    CREATE UNIQUE INDEX effective_user_pkey ON effective_user (effective_key);
  END IF;
END;

Function: public.initialdistribution(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLocationid ALIAS FOR $2;
  _itemlocid INTEGER;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;
  _r RECORD;

BEGIN

--  Make sure the passed itemsite points to a real item
  IF ( (SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  _itemlocSeries := NEXTVAL('itemloc_series_seq');

--  Reassign the location_id for all existing itemlocs if
--  the passed itemsite is already lot/serial controlled
  IF ( ( SELECT (itemsite_controlmethod IN ('L', 'S'))
         FROM itemsite
         WHERE (itemsite_id=pItemsiteid) ) ) THEN

    FOR _r IN SELECT itemloc_id, itemloc_ls_id, itemloc_qty
              FROM itemloc
              WHERE (itemloc_itemsite_id=pItemsiteid) LOOP

--  Create the RL transaction
      SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
      INSERT INTO invhist
      ( invhist_id, invhist_itemsite_id, invhist_series,
        invhist_transtype, invhist_invqty,
        invhist_qoh_before, invhist_qoh_after,
        invhist_comments,
        invhist_invuom, invhist_unitcost, invhist_hasdetail,
        invhist_costmethod, invhist_value_before, invhist_value_after ) 
      SELECT _invhistid, itemsite_id, _itemlocSeries,
             'RL', 0,
             _r.itemloc_qty, _r.itemloc_qty,
             'Initial Distribution',
             uom_name, stdCost(item_id), TRUE,
             itemsite_costmethod, itemsite_value, itemsite_value
      FROM item, itemsite, uom
      WHERE ( (itemsite_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (itemsite_controlmethod <> 'N')
       AND (itemsite_id=pItemsiteid) );

--  Update the itemloc
      UPDATE itemloc
      SET itemloc_location_id=pLocationid
      WHERE (itemloc_id=_r.itemloc_id);

--  Record the detail transaction
      INSERT INTO invdetail
      ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
        invdetail_qty, invdetail_qty_before, invdetail_qty_after )
      VALUES
      ( _invhistid, pLocationid, _r.itemloc_ls_id,
        _r.itemloc_qty, 0, _r.itemloc_qty );

--  Adjust QOH if this itemlocdist is to/from a non-netable location
      IF ( SELECT (NOT location_netable)
           FROM location
           WHERE (location_id=pLocationid) ) THEN

        INSERT INTO invhist
        ( invhist_itemsite_id, invhist_series,
          invhist_transtype, invhist_invqty,
          invhist_qoh_before, invhist_qoh_after,
          invhist_comments,
          invhist_invuom, invhist_unitcost,
          invhist_costmethod, invhist_value_before, invhist_value_after  ) 
        SELECT itemsite_id, _itemlocSeries,
               'NN', (_r.itemloc_qty * -1),
               _r.itemloc_qty, 0,
               'Initial Distribution',
               uom_name, stdCost(item_id),
               itemsite_costmethod, itemsite_value, itemsite_value
        FROM itemsite, item, uom
        WHERE ( (itemsite_item_id=item_id)
         AND (item_inv_uom_id=uom_id)
         AND (itemsite_controlmethod <> 'N')
         AND (itemsite_id=pItemsiteid) );

        UPDATE itemsite
        SET itemsite_nnqoh = (itemsite_nnqoh + _r.itemloc_qty),
            itemsite_qtyonhand = (itemsite_qtyonhand - _r.itemloc_qty) 
        WHERE (itemsite_id=pItemsiteid);

      END IF;

    END LOOP;

  ELSE
--  The passed itemsite is not lot/serial controlled
--  Make sure that there are not any stagnent itemlocs
    DELETE FROM itemloc
    WHERE (itemloc_itemsite_id=pItemsiteid);

--  Create the RL transaction
    SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
    INSERT INTO invhist
    ( invhist_id, invhist_itemsite_id, invhist_series,
      invhist_transtype, invhist_invqty,
      invhist_qoh_before, invhist_qoh_after,
      invhist_comments,
      invhist_invuom, invhist_unitcost, invhist_hasdetail,
      invhist_costmethod, invhist_value_before, invhist_value_after  ) 
    SELECT _invhistid, itemsite_id, _itemlocSeries,
           'RL', 0,
           itemsite_qtyonhand, itemsite_qtyonhand,
           'Initial Distribution',
           uom_name, stdCost(item_id), TRUE,
           itemsite_costmethod, itemsite_value, itemsite_value
    FROM item, itemsite, uom
    WHERE ( (itemsite_item_id=item_id)
     AND (item_inv_uom_id=uom_id)
     AND (itemsite_controlmethod <> 'N')
     AND (itemsite_id=pItemsiteid) );

--  Create the itemloc
    SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
    INSERT INTO itemloc
    ( itemloc_id, itemloc_itemsite_id, itemloc_location_id,
      itemloc_expiration, itemloc_qty )
    SELECT _itemlocid, itemsite_id, pLocationid,
           endOfTime(), itemsite_qtyonhand
    FROM itemsite
    WHERE (itemsite_id=pItemsiteid);

--  Record the detail transaction
    INSERT INTO invdetail
    ( invdetail_invhist_id, invdetail_location_id,
      invdetail_qty, invdetail_qty_before, invdetail_qty_after )
    SELECT _invhistid, pLocationid,
           itemsite_qtyonhand, 0, itemsite_qtyonhand
    FROM itemsite
    WHERE (itemsite_id=pItemsiteid);

--  Adjust QOH if this itemlocdist is to/from a non-netable location
    IF ( SELECT (NOT location_netable)
         FROM location
         WHERE (location_id=pLocationid) ) THEN

      INSERT INTO invhist
      ( invhist_itemsite_id, invhist_series,
        invhist_transtype, invhist_invqty,
        invhist_qoh_before, invhist_qoh_after,
        invhist_comments,
        invhist_invuom, invhist_unitcost,
        invhist_costmethod, invhist_value_before, invhist_value_after  ) 
      SELECT itemsite_id, _itemlocSeries,
             'NN', (itemloc_qty * -1),
             itemloc_qty, 0,
             'Initial Distribution',
             uom_name, stdCost(item_id),
             itemsite_costmethod, itemsite_value, itemsite_value
      FROM itemloc, itemsite, item, uom
      WHERE ( (itemsite_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (itemsite_controlmethod <> 'N')
       AND (itemloc_itemsite_id=itemsite_id)
       AND (itemloc_id=_itemlocid) );

      UPDATE itemsite
      SET itemsite_nnqoh = itemsite_qtyonhand,
          itemsite_qtyonhand = 0 
      FROM itemloc
      WHERE ( (itemloc_itemsite_id=itemsite_id)
       AND (itemloc_id=_itemlocid) );

    END IF;

  END IF;

  RETURN _itemlocid;

END;

Function: public.insertapmemo(api.apmemo)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNew ALIAS FOR $1;
  _result INTEGER;

BEGIN
  IF (pNew.document_type = 'Credit Memo') THEN
    SELECT createAPCreditMemo( getVendId(pNew.vendor_number),
                               pNew.document_number,
                               pNew.po_number,
                               pNew.document_date,
                               pNew.amount,
                               pNew.notes,
                               getGLAccntId(pNew.alternate_prepaid_account),
                               pNew.due_date,
                               getTermsId(pNew.terms) ) INTO _result;
    IF (_result <= 0) THEN
      RAISE EXCEPTION 'Function createAPCreditMemo failed with result = %', _result;
    END IF;
  ELSE
    IF (pNew.document_type = 'Debit Memo') THEN
      SELECT createAPDebitMemo( null, getVendId(pNew.vendor_number),
                                pNew.journal_number,
                                pNew.document_number,
                                pNew.po_number,
                                pNew.document_date,
                                pNew.amount,
                                pNew.notes,
                                getGLAccntId(pNew.alternate_prepaid_account),
                                pNew.due_date,
                                getTermsId(pNew.terms),
                                COALESCE(getCurrId(pNew.currency), baseCurrId()) ) INTO _result;
      IF (_result <= 0) THEN
        RAISE EXCEPTION 'Function createAPDebitMemo failed with result = %', _result;
      END IF;
    ELSE
      RAISE EXCEPTION 'Function insertAPMemo failed, invalid Document Type';
    END IF;
  END IF;

  RETURN TRUE;
END;

Function: public.insertarmemo(api.armemo)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNew ALIAS FOR $1;
  _result INTEGER;

BEGIN
  IF (pNew.document_type = 'Credit Memo') THEN
    SELECT createARCreditMemo( NULL,
                               getCustId(pNew.customer_number),
                               pNew.document_number,
                               pNew.order_number,
                               pNew.document_date,
                               pNew.amount,
                               pNew.notes,
                               getRsnId(pNew.reason_code),
                               getSalescatId(pNew.alternate_prepaid_sales_category),
                               getGLAccntId(pNew.alternate_prepaid_account),
                               pNew.due_date,
                               getTermsId(pNew.terms),
                               getSalesrepId(pNew.sales_rep),
                               pNew.commission_due,
                               pNew.journal_number,
                               COALESCE(getCurrId(pNew.currency), baseCurrId()) ) INTO _result;
    IF (_result <= 0) THEN
      RAISE EXCEPTION 'Function createARCreditMemo failed with result = %', _result;
    END IF;
  ELSE
    IF (pNew.document_type = 'Debit Memo') THEN
      SELECT createARDebitMemo( null, getCustId(pNew.customer_number),
                                pNew.journal_number,
                                pNew.document_number,
                                pNew.order_number,
                                pNew.document_date,
                                pNew.amount,
                                pNew.notes,
                                getRsnId(pNew.reason_code),
                                getSalescatId(pNew.alternate_prepaid_sales_category),
                                getGLAccntId(pNew.alternate_prepaid_account),
                                pNew.due_date,
                                getTermsId(pNew.terms),
                                getSalesrepId(pNew.sales_rep),
                                pNew.commission_due,
                                COALESCE(getCurrId(pNew.currency), baseCurrId()) ) INTO _result;
      IF (_result <= 0) THEN
        RAISE EXCEPTION 'Function createARDebitMemo failed with result = %', _result;
      END IF;
    ELSE
      RAISE EXCEPTION 'Function insertARMemo failed, invalid Document Type';
    END IF;
  END IF;

  RETURN TRUE;
END;

Function: public.insertccard(text, boolean, text, bytea, bytea, bytea, bytea, bytea, bytea, bytea, bytea, bytea, bytea, text)

Returns: boolean

Language: PLPGSQL

This function is generally used to support the _custcreditcard API view

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustomer ALIAS FOR $1;
  pActive ALIAS FOR $2;
  pType ALIAS FOR $3;
  pNumber ALIAS FOR $4;
  pName ALIAS FOR $5;
  pAddr1 ALIAS FOR $6;
  pAddr2 ALIAS FOR $7;
  pCity ALIAS FOR $8;
  pState ALIAS FOR $9;
  pPostal ALIAS FOR $10;
  pCountry ALIAS FOR $11;
  pMonth ALIAS FOR $12;
  pYear ALIAS FOR $13;
  pKey ALIAS FOR $14;
  _type CHAR;
  _number TEXT;
  _month INTEGER;
  _year INTEGER;
  _result INTEGER;

BEGIN
  --Initialize
  _number = pNumber;
  _month = CAST(encode(pMonth, 'escape') AS integer);
  _year = CAST(encode(pYear, 'escape') AS integer);

  -- Check Card holder info
  IF (pName IS NULL) THEN
      RAISE EXCEPTION 'The name of the card holder must be entered';
  END IF;
  IF (pAddr1 IS NULL OR pAddr1 = '') THEN
      RAISE EXCEPTION 'The first address line must be entered';
  END IF;
  IF (pCity IS NULL OR pCity = '') THEN
      RAISE EXCEPTION 'The city must be entered';
  END IF;
  IF (pState IS NULL OR pState = '') THEN
      RAISE EXCEPTION 'The state must be entered';
  END IF;
  IF (pPostal IS NULL OR pPostal = '') THEN
      RAISE EXCEPTION 'The zip code must be entered';
  END IF;
  IF (pCountry IS NULL OR pCountry = '') THEN
      RAISE EXCEPTION 'The country must be entered';
  END IF;
  IF (pMonth IS NULL OR pMonth = '') THEN
      RAISE EXCEPTION 'The Expiration Month must be entered';
  END IF;
  IF (_month < 1 OR _month > 12) THEN
      RAISE EXCEPTION 'Valid Expiration Months are 01 through 12';
  END IF;
  IF (LENGTH(pYear) <> 4) THEN
      RAISE EXCEPTION 'Valid Expiration Years are CCYY in format';
  END IF;
  IF (_year < 1970 OR _year > 2100) THEN
      RAISE EXCEPTION 'Valid Expiration Years are 1970 through 2100';
  END IF;
  
  -- Check Number Length
  IF ((NOT _number ~  '[0-9]{13,16}') OR (LENGTH(_number) = 14) OR (LENGTH(_number) > 16)) THEN
    RAISE EXCEPTION 'The credit card number must be all numeric (no spaces or hyphens) and must be 13, 15 or 16 characters in length';
  END IF;
 
  -- Convert Type
  IF (pType = 'Visa') THEN
    _type  = 'V';
  ELSE
    IF (pType = 'Master Card') THEN
      _type  = 'M';
    ELSE
      IF (pType = 'American Express') THEN
        _type  = 'A';
      ELSE
        IF (pType = 'Discover') THEN
          _type  = 'D';
        ELSE
          RAISE EXCEPTION 'You must select Master Card, Visa, American 
                            Express or Discover as the credit card type.';
        END IF;
      END IF;
    END IF;
  END IF;
  
  -- Check Card Specific Data
  SELECT editccnumber(_number, _type) INTO _result;

  IF (_result = -1) THEN
    RAISE EXCEPTION 'You must select Master Card, Visa, American 
                      Express or Discover as the credit card type.';
  END IF;
  IF (_result = -2) THEN
    RAISE EXCEPTION 'The length of a Master Card credit card number
                      has to be 16 digits.';
  END IF;
  IF (_result = -3) THEN
    RAISE EXCEPTION 'The length of a Visa credit card number
                      has to be either 13 or 16 digits.';
  END IF;
  IF (_result = -4) THEN
    RAISE EXCEPTION 'The length of an American Express credit card
                      number has to be 15 digits.';
  END IF;
  IF (_result = -5) THEN
    RAISE EXCEPTION 'The length of a Discover credit card number 
                      has to be 16 digits.';
  END IF;
   IF (_result = -6) THEN
    RAISE EXCEPTION 'The first two digits for a valid Master Card
                      number must be between 51 and 55';
  END IF;
  IF (_result = -7) THEN
    RAISE EXCEPTION 'The first digit for a valid Visa number must
                      be 4';
  END IF;
   IF (_result = -8) THEN
    RAISE EXCEPTION 'The first two digits for a valid American
                      Express number must be 34 or 37.';
  END IF;
  IF (_result = -9) THEN
    RAISE EXCEPTION 'The first four digits for a valid Discover
                      Express number must be 6011.';
  END IF;
  IF ((_result = -10) AND NOT fetchmetricbool('CCTest')) THEN
    RAISE EXCEPTION 'The credit card number that you have provided
                      is not valid.';
  END IF;
  IF (_result < -10) THEN
    RAISE EXCEPTION 'Invalid Credit Card Information';
  END IF;

  -- Insert Record

  INSERT INTO ccard ( 
    ccard_seq, 
    ccard_cust_id,
    ccard_active, 
    ccard_name, 
    ccard_address1,
    ccard_address2,
    ccard_city, 
    ccard_state, 
    ccard_zip,
    ccard_country, 
    ccard_number,
    ccard_month_expired, 
    ccard_year_expired, 
    ccard_type)
    VALUES 
    ((SELECT COALESCE(MAX(ccard_seq), 0) + 10
      FROM ccard 
      WHERE (ccard_cust_id =getCustId(pCustomer))),
     getCustId(pCustomer),
     COALESCE(pActive),
     encrypt(setbytea(pName), setbytea(pKey), 'bf'),
     encrypt(setbytea(pAddr1), setbytea(pKey), 'bf'),
     encrypt(setbytea(pAddr2), setbytea(pKey), 'bf'),
     encrypt(setbytea(pCity), setbytea(pKey), 'bf'),
     encrypt(setbytea(pState), setbytea(pKey), 'bf'),
     encrypt(setbytea(pPostal), setbytea(pKey), 'bf'),
     encrypt(setbytea(pCountry), setbytea(pKey), 'bf'),
     encrypt(setbytea(pNumber), setbytea(pKey), 'bf'),
     encrypt(setbytea(pMonth), setbytea(pKey), 'bf'),
     encrypt(setbytea(pYear), setbytea(pKey), 'bf'),
     _type );

  RETURN true;
END;

Function: public.insertcreditmemo(api.creditmemo)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
	pNew ALIAS FOR $1;
BEGIN
	-- NOTE: (SELECT getCustId(...)) seems redundant, but it actually produces
	-- a HUGE performance increase because it makes the Postgres query planner
	-- use an index scan rather than an sequential table scan on cust_id
  INSERT INTO cmhead (
		cmhead_number,
		cmhead_posted,
		cmhead_invcnumber,
                cmhead_custponumber,
		cmhead_cust_id,
		cmhead_docdate,
		cmhead_shipto_id,
		cmhead_shipto_name,
		cmhead_shipto_address1,
		cmhead_shipto_address2,
		cmhead_shipto_address3,
		cmhead_shipto_city,
		cmhead_shipto_state,
		cmhead_shipto_zipcode,
		cmhead_shipto_country,
		cmhead_salesrep_id,
		cmhead_freight,
		cmhead_misc,
		cmhead_comments,
		cmhead_printed,
		cmhead_billtoname,
		cmhead_billtoaddress1,
		cmhead_billtoaddress2,
		cmhead_billtoaddress3,
		cmhead_billtocity,
		cmhead_billtostate,
		cmhead_billtozip,
		cmhead_billtocountry,
		cmhead_hold,
		cmhead_commission,
		cmhead_misc_accnt_id,
		cmhead_misc_descrip,
		cmhead_rsncode_id,
		cmhead_curr_id,
		cmhead_taxzone_id,
                cmhead_gldistdate,
                cmhead_rahead_id
		)
	 SELECT
		(CASE -- use a case here so we don't unnecessarily fetch a new CM number
			WHEN pNew.memo_number IS NULL THEN fetchCMNumber()
			ELSE pNew.memo_number
		END),
		FALSE, -- posted
		pNew.apply_to,
		pNew.customer_po_number,
		cust_id,
		COALESCE(pNew.memo_date, CURRENT_DATE),
		COALESCE(shipto_id,-1),
		pNew.shipto_name,
		pNew.shipto_address1,
		pNew.shipto_address2,
		pNew.shipto_address3,
		pNew.shipto_city,
		pNew.shipto_state,
		pNew.shipto_postal_code,
		pNew.shipto_country,
		COALESCE(getSalesRepId(pNew.sales_rep),shipto_salesrep_id,cust_salesrep_id),
		COALESCE(pNew.freight, 0),
		COALESCE(pNew.misc_charge_amount, 0),
		pNew.notes,
		FALSE, -- printed
		COALESCE(pNew.billto_name, invchead_billto_name, cust_name),
		COALESCE(pNew.billto_address1, invchead_billto_address1, addr_line1),
		COALESCE(pNew.billto_address2, invchead_billto_address2, addr_line2),
		COALESCE(pNew.billto_address3, invchead_billto_address3, addr_line3),
		COALESCE(pNew.billto_city, invchead_billto_city, addr_city),
		COALESCE(pNew.billto_state, invchead_billto_state, addr_state),
		COALESCE(pNew.billto_postal_code, invchead_billto_zipcode, addr_postalcode),
		COALESCE(pNew.billto_country, invchead_billto_country, addr_country),
		COALESCE(pNew.on_hold, FALSE),
		COALESCE(pNew.commission, 0),
		COALESCE(getGlAccntId(pNew.misc_charge_credit_account),-1),
		pNew.misc_charge_description,
		(SELECT rsncode_id FROM rsncode WHERE rsncode_code = pNew.reason_code),
		COALESCE(getCurrId(pNew.currency),cust_curr_id,basecurrid()),
                CASE WHEN pNew.tax_zone = 'None' THEN NULL
                     ELSE COALESCE(getTaxZoneID(pNew.tax_zone),cust_taxzone_id)
                END,
                NULL,
                NULL
	FROM custinfo
		LEFT OUTER JOIN shiptoinfo ON (shipto_id=(SELECT CASE
			WHEN getShiptoId(pNew.customer_number,pNew.shipto_number) IS NOT NULL
				THEN getShiptoId(pNew.customer_number,pNew.shipto_number)
			ELSE (SELECT shipto_id FROM shiptoinfo WHERE shipto_cust_id=cust_id AND shipto_default)
		END))
                LEFT OUTER JOIN invchead ON (invchead_id=getInvcheadId(pNEW.apply_to))
                LEFT OUTER JOIN cntct ON (cntct_id=cust_cntct_id)
                LEFT OUTER JOIN addr ON (addr_id=cntct_addr_id)
	WHERE cust_id = (CASE
		WHEN pNew.customer_number IS NOT NULL THEN (SELECT getCustId(pNew.customer_number))
		ELSE (SELECT invchead_cust_id FROM invchead WHERE invchead_invcnumber = pNew.apply_to)
	END);
	RETURN TRUE;
END;

Function: public.insertcreditmemoline(api.creditmemoline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNew ALIAS FOR $1;
  _check INTEGER;
  _r RECORD;

BEGIN
  SELECT cmhead_id INTO _check
  FROM cmhead
  WHERE (cmhead_id=getCmheadId(pNew.memo_number, FALSE));
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Credit Memo # % not found', pNew.memo_number;
  END IF;

  INSERT INTO cmitem ( cmitem_cmhead_id,
                       cmitem_linenumber,
                       cmitem_itemsite_id,
                       cmitem_qtycredit,
                       cmitem_qtyreturned,
                       cmitem_unitprice,
                       cmitem_comments,
                       cmitem_rsncode_id,
                       cmitem_taxtype_id,
                       cmitem_qty_uom_id,
                       cmitem_qty_invuomratio,
                       cmitem_price_uom_id,
                       cmitem_price_invuomratio	)
  SELECT cmhead_id,
         COALESCE(pNew.line_number,
                  (SELECT (COALESCE(MAX(cmitem_linenumber), 0) + 1)
                   FROM cmitem WHERE (cmitem_cmhead_id=cmhead_id))),
         COALESCE(itemsite_id, -1),
         COALESCE(pNew.qty_to_credit, 0),
         COALESCE(pNew.qty_returned, 0),
         COALESCE(pNew.net_unit_price, 0),
         pNew.notes,
         getRsnId(pNew.reason_code),
         taxtype_id,
         COALESCE(getUomId(pNew.qty_uom), item_inv_uom_id),
         CASE
           WHEN item_id IS NOT NULL THEN itemuomtouomratio(item_id, COALESCE(getUomId(pNew.qty_uom),item_inv_uom_id),item_inv_uom_id)
           ELSE 1
         END,
         COALESCE(getUomId(pNew.price_uom),item_price_uom_id),
         CASE
           WHEN item_id IS NOT NULL THEN itemuomtouomratio(item_id, COALESCE(getUomId(pNew.price_uom),item_price_uom_id),item_price_uom_id)
           ELSE 1
        END
  FROM cmhead LEFT OUTER JOIN item ON (item_id=getItemId(pNew.item_number))
              LEFT OUTER JOIN itemsite ON (itemsite_item_id=item_id AND itemsite_warehous_id=getWarehousId(pNew.recv_site, 'ALL'))
              LEFT OUTER JOIN taxtype ON (taxtype_id=CASE WHEN pNew.tax_type IS NULL THEN getItemTaxType(item_id,cmhead_taxzone_id)
                                                          WHEN pNew.tax_type = 'None' THEN NULL
                                                          ELSE getTaxTypeId(pNew.tax_type)
                                                     END)
  WHERE (cmhead_id=getCmheadId(pNew.memo_number, FALSE));

  RETURN TRUE;
END;

Function: public.insertflgroup(integer, integer, integer, integer, boolean)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid  ALIAS FOR $1;
  pPeriodid  ALIAS FOR $2;
  pFlgrpid   ALIAS FOR $3;
  pLevel     ALIAS FOR $4;
  pSummarize ALIAS FOR $5;

BEGIN
  RETURN insertFlGroup(pFlheadid, pPeriodid, pFlgrpid, pLevel, pSummarize, NULL);
END;

Function: public.insertflgroup(integer, integer, integer, integer, boolean, bpchar)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid  ALIAS FOR $1;
  pPeriodid  ALIAS FOR $2;
  pFlgrpid   ALIAS FOR $3;
  pLevel     ALIAS FOR $4;
  pSummarize ALIAS FOR $5;
  pInterval  ALIAS FOR $6;

BEGIN
  RETURN insertFlGroup(pFlheadid, pPeriodid, pFlgrpid, pLevel, pSummarize, pInterval, NULL);
END;

Function: public.insertflgroup(integer, integer, integer, integer, boolean, bpchar, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlheadid  ALIAS FOR $1;
  pPeriodid  ALIAS FOR $2;
  pFlgrpid   ALIAS FOR $3;
  pLevel     ALIAS FOR $4;
  pSummarize ALIAS FOR $5;
  pInterval  ALIAS FOR $6;
  pPrjid     ALIAS FOR $7;

  _subtotal BOOLEAN;
  _r RECORD;
  _g RECORD;
  _all BOOLEAN;

BEGIN

  _all = COALESCE(pPrjid,-1) = -1;
  
-- Check to see if this group wants a subtotal
  _subtotal := FALSE;
  IF (pFlgrpid != -1) THEN
    SELECT COALESCE(flgrp_subtotal, FALSE) INTO _subtotal
      FROM flgrp
     WHERE ((flgrp_flhead_id=pFlheadid)
       AND  (flgrp_id=pFlgrpid));
  END IF;

  FOR _r IN SELECT 'G' AS type, flgrp_id AS type_id,
                   flgrp_order AS orderby,
                   flgrp_summarize AS summarize,
                   flgrp_subtract AS subtract,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showstart)) THEN NULL
                        ELSE 0.00
                   END AS beginning,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showend)) THEN NULL
                        ELSE 0.00
                   END AS ending,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showdelta)) THEN NULL
                        ELSE 0.00
                   END AS debits,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showdelta)) THEN NULL
                        ELSE 0.00
                   END AS credits,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showbudget)) THEN NULL
                        ELSE 0.00
                   END AS budget,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showdiff)) THEN NULL
                        ELSE 0.00
                   END AS diff,
                   CASE WHEN(flgrp_summarize AND (NOT flgrp_showcustom)) THEN NULL
                        ELSE 0.00
                   END AS custom,
                   CASE WHEN(flgrp_showstartprcnt) THEN 0.00
                        ELSE NULL
                   END AS beginningprcnt,
                   CASE WHEN(flgrp_showendprcnt) THEN 0.00
                        ELSE NULL
                   END AS endingprcnt,
                   CASE WHEN(flgrp_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS debitsprcnt,
                   CASE WHEN(flgrp_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS creditsprcnt,
                   CASE WHEN(flgrp_showbudgetprcnt) THEN 0.00
                        ELSE NULL
                   END AS budgetprcnt,
                   CASE WHEN(flgrp_showdiffprcnt) THEN 0.00
                        ELSE NULL
                   END AS diffprcnt,
                   CASE WHEN(flgrp_showcustomprcnt) THEN 0.00
                        ELSE NULL
                   END AS customprcnt,
                   -1 AS accnt_id,
                   '' AS accnt_number
              FROM flgrp
             WHERE ((flgrp_flgrp_id=pFlgrpid)
               AND  (flgrp_flhead_id=pFlheadid))
             UNION ALL
            SELECT 'I' AS type, flitem_id AS type_id,
                   flitem_order AS orderby,
                   FALSE AS summarize,
                   flitem_subtract AS subtract,
                   CASE WHEN (flitem_showstart AND (first_trialbal_id IS NULL)) THEN 0.00
                        WHEN (flitem_showstart) THEN normalizeTrialBal(first_trialbal_id, 'B')
                        ELSE NULL
                   END AS beginning,
                   CASE WHEN (flitem_showend AND (last_trialbal_id IS NULL)) THEN 0.00
                        WHEN (flitem_showend) THEN normalizeTrialBal(last_trialbal_id, 'E')
                        ELSE NULL
                   END AS ending,
                   CASE WHEN (flitem_showdelta) THEN sum_trialbal_debits
                        ELSE NULL
                   END AS debits,
                   CASE WHEN (flitem_showdelta) THEN sum_trialbal_credits
                        ELSE NULL
                   END AS credits,
                   CASE WHEN ((flitem_showbudget) AND (accnt_type IN ('R','E')) AND flhead_type IN ('I','C','A')) THEN COALESCE(sum_budget_amount,0)
                        WHEN ((flitem_showbudget) AND (accnt_type IN ('R','E')) AND flhead_type = 'B' ) THEN
                                (SELECT COALESCE(SUM(b.budget_amount),0)
                                FROM budget b,
                                        (SELECT ytd.period_id AS ytd_period_id
                                        FROM period cp, period ytd
                                        WHERE ((cp.period_id = last_flitem_period_id)
                                        AND (ytd.period_start <= cp.period_start)
                                AND (ytd.period_yearperiod_id = cp.period_yearperiod_id))) AS periods
                                WHERE ((b.budget_accnt_id=accnt_id)
                                AND (b.budget_period_id=ytd_period_id)))
                        WHEN ((flitem_showbudget) AND (accnt_type IN ('A','L','Q')) AND flhead_type = 'C') THEN calccashbudget(accnt_id,last_flitem_period_id,pInterval)
                        ELSE COALESCE(last_budget_amount,0)
                   END AS budget,
                   CASE WHEN (flitem_showdiff AND (first_trialbal_id IS NULL)) THEN 0.00
                        WHEN (flitem_showdiff) THEN COALESCE(normalizeTrialBal(last_trialbal_id, 'E') - normalizeTrialBal(first_trialbal_id, 'B'), 0.00)
                        ELSE NULL
                   END AS diff,
                   CASE WHEN (NOT flitem_showcustom) THEN NULL
                        WHEN (flitem_custom_source='S' AND (first_trialbal_id IS NOT NULL)) THEN normalizeTrialBal(first_trialbal_id, 'B')
                        WHEN (flitem_custom_source='E' AND (first_trialbal_id IS NOT NULL)) THEN normalizeTrialBal(last_trialbal_id, 'E')
                        WHEN (flitem_custom_source='D') THEN sum_trialbal_debits
                        WHEN (flitem_custom_source='C') THEN sum_trialbal_credits
                        WHEN (flitem_custom_source='B') THEN (
                                CASE
                                  WHEN (accnt_type IN ('R','E')) THEN sum_budget_amount
                                  ELSE last_budget_amount
                                END)
                        WHEN (flitem_custom_source='F' AND  (first_trialbal_id IS NOT NULL)) THEN COALESCE(normalizeTrialBal(last_trialbal_id, 'E') - normalizeTrialBal(first_trialbal_id, 'B'), 0.00)
                        ELSE 0.00
                   END AS custom,
                   CASE WHEN(flitem_showstartprcnt) THEN 0.00
                        ELSE NULL
                   END AS beginningprcnt,
                   CASE WHEN(flitem_showendprcnt) THEN 0.00
                        ELSE NULL
                   END AS endingprcnt,
                   CASE WHEN(flitem_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS debitsprcnt,
                   CASE WHEN(flitem_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS creditsprcnt,
                   CASE WHEN(flitem_showbudgetprcnt) THEN 0.00
                        ELSE NULL
                   END AS budgetprcnt,
                   CASE WHEN(flitem_showdiffprcnt) THEN 0.00
                        ELSE NULL
                   END AS diffprcnt,
                   CASE WHEN(flitem_showcustomprcnt) THEN 0.00
                        ELSE NULL
                   END AS customprcnt,
                   accnt_id,
                   public.formatglaccount(accnt_id) AS accnt_number
              FROM
                (SELECT 
                  flhead_type,flitem_id,flitem_order,flitem_subtract,flitem_showstart,flitem_showend,
                  flitem_showdelta,flitem_showbudget,flitem_showdiff,flitem_showcustom,
                  flitem_custom_source,flitem_showstartprcnt,flitem_showendprcnt,flitem_showdeltaprcnt,
                  flitem_showbudgetprcnt,flitem_showdiffprcnt,flitem_showcustomprcnt,
                  accnt_id,accnt_type,
                  FIRST(trialbal_id) AS first_trialbal_id, LAST(trialbal_id) AS last_trialbal_id,
                  SUM(trialbal_debits) AS sum_trialbal_debits, SUM(trialbal_credits) AS sum_trialbal_credits, 
                  LAST(flitem_period_id) AS last_flitem_period_id,
                  SUM(budget_amount) AS sum_budget_amount, LAST(budget_amount) AS last_budget_amount
                  FROM
                (SELECT period_id AS flitem_period_id, period_start,flhead_type,flitem_id,flitem_order,flitem_subtract,flitem_showstart,flitem_showend,
                        flitem_showdelta,flitem_showbudget,flitem_showdiff,flitem_showcustom,
                        flitem_custom_source,flitem_showstartprcnt,flitem_showendprcnt,flitem_showdeltaprcnt,
                        flitem_showbudgetprcnt,flitem_showdiffprcnt,flitem_showcustomprcnt,
                        accnt_id,accnt_type,COALESCE(trialbal_id,getlasttrialbalid(accnt_id,period_id)) as trialbal_id,COALESCE(trialbal_debits,0) as trialbal_debits,
                        COALESCE(trialbal_credits,0) AS trialbal_credits,COALESCE(budget_amount,0) AS budget_amount
                   FROM (SELECT period_id, period_start, flhead_type, flitem_id,flitem_order,flitem_subtract,flitem_showstart,flitem_showend,
                                flitem_showdelta,flitem_showbudget,flitem_showdiff,flitem_showcustom,flitem_custom_source,flitem_showstartprcnt,
                                flitem_showendprcnt,flitem_showdeltaprcnt,flitem_showbudgetprcnt,flitem_showdiffprcnt,flitem_showcustomprcnt,
                                accnt_id, accnt_type
                        FROM  period,flaccnt
                        WHERE ((flitem_flhead_id=pFlheadid)
                        AND (flitem_flgrp_id=pFlgrpid)
                        AND (_all OR prj_id=pPrjId)
                        AND (period_id IN  (SELECT * FROM getperiodid(pPeriodId,pInterval))))
                        ORDER BY flitem_id
                        ) AS flitem
                   LEFT OUTER JOIN trialbal
                     ON ((trialbal_accnt_id=accnt_id)
                     AND (trialbal_period_id=period_id))
                   LEFT OUTER JOIN budget
                     ON ((budget_accnt_id=accnt_id)
                     AND (budget_period_id=period_id))
             ORDER BY accnt_id, period_start) AS data
             GROUP BY flhead_type,flitem_id,flitem_order,flitem_subtract,flitem_showstart,flitem_showend,
                flitem_showdelta,flitem_showbudget,flitem_showdiff,flitem_showcustom,
                flitem_custom_source,flitem_showstartprcnt,flitem_showendprcnt,flitem_showdeltaprcnt,
                flitem_showbudgetprcnt,flitem_showdiffprcnt,flitem_showcustomprcnt,accnt_id,accnt_type) AS agg
             UNION ALL
            SELECT 'S' AS type, flspec_id AS type_id,
                   flspec_order AS orderby,
                   FALSE AS summarize,
                   flspec_subtract AS subtract,
                   CASE WHEN (flspec_showstart) THEN findSpecialFinancial('S', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS beginning,
                   CASE WHEN (flspec_showend) THEN findSpecialFinancial('E', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS ending,
                   CASE WHEN (flspec_showdelta) THEN findSpecialFinancial('D', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS debits,
                   CASE WHEN (flspec_showdelta) THEN findSpecialFinancial('C', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS credits,
                   CASE WHEN (flspec_showbudget) THEN findSpecialFinancial('B', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS budget,
                   CASE WHEN (flspec_showdiff) THEN findSpecialFinancial('E', flspec_type, pPeriodid) - findSpecialFinancial('S', flspec_type, pPeriodid)
                        ELSE NULL
                   END AS diff,
                   CASE WHEN (NOT flspec_showcustom) THEN NULL
                        WHEN (flspec_custom_source='F') THEN findSpecialFinancial('E', flspec_type, pPeriodid) - findSpecialFinancial('S', flspec_type, pPeriodid)
                        WHEN (flspec_custom_source IN ('S', 'E', 'D', 'C', 'B')) THEN findSpecialFinancial(flspec_custom_source, flspec_type, pPeriodid)
                        ELSE 0.00
                   END AS custom,
                   CASE WHEN(flspec_showstartprcnt) THEN 0.00
                        ELSE NULL
                   END AS beginningprcnt,
                   CASE WHEN(flspec_showendprcnt) THEN 0.00
                        ELSE NULL
                   END AS endingprcnt,
                   CASE WHEN(flspec_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS debitsprcnt,
                   CASE WHEN(flspec_showdeltaprcnt) THEN 0.00
                        ELSE NULL
                   END AS creditsprcnt,
                   CASE WHEN(flspec_showbudgetprcnt) THEN 0.00
                        ELSE NULL
                   END AS budgetprcnt,
                   CASE WHEN(flspec_showdiffprcnt) THEN 0.00
                        ELSE NULL
                   END AS diffprcnt,
                   CASE WHEN(flspec_showcustomprcnt) THEN 0.00
                        ELSE NULL
                   END AS customprcnt,
                   -1 AS accnt_id,
                   '' AS accnt_number
              FROM flspec
             WHERE ((flspec_flgrp_id=pFlgrpid)
               AND  (flspec_flhead_id=pFlheadid))
          ORDER BY orderby, accnt_number LOOP

    IF (_r.type = 'G') THEN

-- Create a record for the items sub items to be attached to and be able to update the total
      INSERT INTO flrpt
             (flrpt_flhead_id, flrpt_period_id, flrpt_username,
              flrpt_order,
              flrpt_level, flrpt_type, flrpt_type_id,
              flrpt_beginning, flrpt_ending,
              flrpt_debits, flrpt_credits, flrpt_budget, flrpt_diff, flrpt_custom,
              flrpt_beginningprcnt, flrpt_endingprcnt,
              flrpt_debitsprcnt, flrpt_creditsprcnt, flrpt_budgetprcnt, flrpt_diffprcnt, flrpt_customprcnt,
              flrpt_parent_id, flrpt_interval)
      VALUES (pFlheadid, pPeriodid, getEffectiveXtUser(),
              (COALESCE(( SELECT MAX(flrpt_order)
                            FROM flrpt
                           WHERE ((flrpt_flhead_id=pFlheadid)
                             AND  (flrpt_period_id=pPeriodid)
                             AND (flrpt_interval=pInterval)
                             AND  (flrpt_username=getEffectiveXtUser()))
                        ), 1) + 1),
              pLevel, _r.type, _r.type_id,
              _r.beginning, _r.ending,
              _r.debits, _r.credits, _r.budget, _r.diff, _r.custom,
              _r.beginningprcnt, _r.endingprcnt,
              _r.debitsprcnt, _r.creditsprcnt, _r.budgetprcnt, _r.diffprcnt, _r.customprcnt,
              pFlgrpid, pInterval);

      PERFORM insertFlGroup(pFlheadid, pPeriodid, _r.type_id, (pLevel + 1), (pSummarize OR _r.summarize), pInterval, pPrjid);

-- Update the parent item
      SELECT COALESCE(flrpt_beginning, 0.00) AS beginning,
             COALESCE(flrpt_ending, 0.00) AS ending,
             COALESCE(flrpt_debits, 0.00) AS debits,
             COALESCE(flrpt_credits, 0.00) AS credits,
             COALESCE(flrpt_budget, 0.00) AS budget,
             COALESCE(flrpt_diff, 0.00) AS diff,
             COALESCE(flrpt_custom, 0.00) AS custom INTO _g
        FROM flrpt
       WHERE ((flrpt_flhead_id=pFlheadid)
         AND  (flrpt_period_id=pPeriodid)
          AND (flrpt_interval=pInterval)
         AND  (flrpt_username=getEffectiveXtUser())
         AND  (flrpt_type=_r.type)
         AND  (flrpt_type_id=_r.type_id));
      IF (_r.subtract) THEN
        UPDATE flrpt
           SET flrpt_beginning = flrpt_beginning - _g.beginning,
               flrpt_ending    = flrpt_ending    - _g.ending,
               flrpt_debits    = flrpt_debits    - _g.debits,
               flrpt_credits   = flrpt_credits   - _g.credits,
               flrpt_budget    = flrpt_budget    - _g.budget,
               flrpt_diff      = flrpt_diff      - _g.diff,
               flrpt_custom    = flrpt_custom    - _g.custom
         WHERE ((flrpt_flhead_id=pFlheadid)
           AND  (flrpt_period_id=pPeriodid)
           AND  (flrpt_interval=pInterval)
           AND  (flrpt_username=getEffectiveXtUser())
           AND  (flrpt_type='G')
           AND  (flrpt_type_id=pFlgrpid));
      ELSE
        UPDATE flrpt
           SET flrpt_beginning = flrpt_beginning + _g.beginning,
               flrpt_ending    = flrpt_ending    + _g.ending,
               flrpt_debits    = flrpt_debits    + _g.debits,
               flrpt_credits   = flrpt_credits   + _g.credits,
               flrpt_budget    = flrpt_budget    + _g.budget,
               flrpt_diff      = flrpt_diff      + _g.diff,
               flrpt_custom    = flrpt_custom    + _g.custom
         WHERE ((flrpt_flhead_id=pFlheadid)
           AND  (flrpt_period_id=pPeriodid)
           AND  (flrpt_interval=pInterval)
           AND  (flrpt_username=getEffectiveXtUser())
           AND  (flrpt_type='G')
           AND  (flrpt_type_id=pFlgrpid));
      END IF;

-- If we are summarizing then we need to remove the record we created now that we have updated the total
      IF (pSummarize) THEN
        DELETE FROM flrpt
         WHERE ((flrpt_flhead_id=pFlheadid)
          AND  (flrpt_period_id=pPeriodid)
          AND  (flrpt_interval=pInterval)
          AND  (flrpt_username=getEffectiveXtUser())
          AND  (flrpt_type=_r.type)
          AND  (flrpt_type_id=_r.type_id));
      END IF;

    ELSE
      IF (_r.type = 'I' OR _r.type = 'S' ) THEN

-- If we are not summarizing then create a new entry for this record
        IF (NOT pSummarize) THEN
          INSERT INTO flrpt
                 (flrpt_flhead_id, flrpt_period_id, flrpt_username,
                  flrpt_order,
                  flrpt_level, flrpt_type, flrpt_type_id,
                  flrpt_beginning, flrpt_ending,
                  flrpt_debits, flrpt_credits, flrpt_budget, flrpt_diff, flrpt_custom,
                  flrpt_beginningprcnt, flrpt_endingprcnt,
                  flrpt_debitsprcnt, flrpt_creditsprcnt, flrpt_budgetprcnt, flrpt_diffprcnt, flrpt_customprcnt,
                  flrpt_parent_id,flrpt_accnt_id,flrpt_interval)
          VALUES (pFlheadid, pPeriodid, getEffectiveXtUser(),
                  (COALESCE(( SELECT MAX(flrpt_order)
                               FROM flrpt
                              WHERE ((flrpt_flhead_id=pFlheadid)
                                AND  (flrpt_period_id=pPeriodid)
                                AND  (flrpt_interval=pInterval)
                                AND  (flrpt_username=getEffectiveXtUser()))
                            ), 1) + 1),
                  pLevel, _r.type, _r.type_id,
                  _r.beginning, _r.ending,
                  _r.debits, _r.credits, _r.budget, _r.diff, _r.custom,
                  _r.beginningprcnt, _r.endingprcnt,
                  _r.debitsprcnt, _r.creditsprcnt, _r.budgetprcnt, _r.diffprcnt, _r.customprcnt,
                  pFlgrpid,_r.accnt_id,pInterval);
        END IF;

-- Update the parent item
        IF (_r.subtract) THEN
          UPDATE flrpt
             SET flrpt_beginning = flrpt_beginning - COALESCE(_r.beginning, 0.00),
                 flrpt_ending    = flrpt_ending    - COALESCE(_r.ending, 0.00),
                 flrpt_debits    = flrpt_debits    - COALESCE(_r.debits, 0.00),
                 flrpt_credits   = flrpt_credits   - COALESCE(_r.credits, 0.00),
                 flrpt_budget    = flrpt_budget    - COALESCE(_r.budget, 0.00),
                 flrpt_diff      = flrpt_diff      - COALESCE(_r.diff, 0.00),
                 flrpt_custom    = flrpt_custom    - COALESCE(_r.custom, 0.00)
           WHERE ((flrpt_flhead_id=pFlheadid)
             AND  (flrpt_period_id=pPeriodid)
             AND  (flrpt_interval=pInterval)
             AND  (flrpt_username=getEffectiveXtUser())
             AND  (flrpt_type='G')
             AND  (flrpt_type_id=pFlgrpid));
        ELSE
          UPDATE flrpt
             SET flrpt_beginning = flrpt_beginning + COALESCE(_r.beginning, 0.00),
                 flrpt_ending    = flrpt_ending    + COALESCE(_r.ending, 0.00),
                 flrpt_debits    = flrpt_debits    + COALESCE(_r.debits, 0.00),
                 flrpt_credits   = flrpt_credits   + COALESCE(_r.credits, 0.00),
                 flrpt_budget    = flrpt_budget    + COALESCE(_r.budget, 0.00),
                 flrpt_diff      = flrpt_diff      + COALESCE(_r.diff, 0.00),
                 flrpt_custom    = flrpt_custom    + COALESCE(_r.custom, 0.00)
           WHERE ((flrpt_flhead_id=pFlheadid)
             AND  (flrpt_interval=pInterval)
             AND  (flrpt_period_id=pPeriodid)
             AND  (flrpt_username=getEffectiveXtUser())
             AND  (flrpt_type='G')
             AND  (flrpt_type_id=pFlgrpid));
        END IF;

      END IF;
    END IF;

  END LOOP;

  IF (NOT pSummarize) THEN
-- If this group wants a summarized line create it here.
    IF (_subtotal) THEN
      INSERT INTO flrpt
             (flrpt_flhead_id, flrpt_period_id, flrpt_username,
              flrpt_order,
              flrpt_level, flrpt_type, flrpt_type_id,
              flrpt_beginning, flrpt_ending,
              flrpt_debits, flrpt_credits, flrpt_budget, flrpt_diff, flrpt_custom,
              flrpt_beginningprcnt, flrpt_endingprcnt,
              flrpt_debitsprcnt, flrpt_creditsprcnt, flrpt_budgetprcnt, flrpt_diffprcnt, flrpt_customprcnt,
              flrpt_parent_id, flrpt_altname,flrpt_interval )
      SELECT pFlheadid, pPeriodid, getEffectiveXtUser(),
             (COALESCE(( SELECT MAX(flrpt_order)
                           FROM flrpt
                          WHERE ((flrpt_flhead_id=pFlheadid)
                            AND  (flrpt_period_id=pPeriodid)
                            AND  (flrpt_interval=pInterval)
                            AND  (flrpt_username=getEffectiveXtUser()))
                       ), 1) + 1),
             pLevel, 'T', -1,
             CASE WHEN (flgrp_showstart) THEN flrpt_beginning
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showend) THEN flrpt_ending
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdelta) THEN flrpt_debits
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdelta) THEN flrpt_credits
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showbudget) THEN flrpt_budget
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdiff) THEN flrpt_diff
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showcustom) THEN flrpt_custom
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showstartprcnt) THEN flrpt_beginningprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showendprcnt) THEN flrpt_endingprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdeltaprcnt) THEN flrpt_debitsprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdeltaprcnt) THEN flrpt_creditsprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showbudgetprcnt) THEN flrpt_budgetprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showdiffprcnt) THEN flrpt_diffprcnt
                  ELSE NULL
             END,
             CASE WHEN (flgrp_showcustomprcnt) THEN flrpt_customprcnt
                  ELSE NULL
             END,
             pFlgrpid,
             CASE WHEN (flgrp_usealtsubtotal) THEN flgrp_altsubtotal
                  ELSE NULL
             END, pInterval
        FROM flrpt, flgrp
       WHERE ((flrpt_flhead_id=flgrp_flhead_id)
         AND  (flrpt_type_id=flgrp_id)
         AND  (flrpt_flhead_id=pFlheadid)
         AND  (flrpt_period_id=pPeriodid)
         AND  (flrpt_interval=pInterval)
         AND  (flrpt_username=getEffectiveXtUser())
         AND  (flrpt_type='G')
         AND  (flrpt_type_id=pFlgrpid));
    END IF;
  END IF;

  return TRUE;
END;

Function: public.insertgltransaction(integer, text, text, text, text, integer, integer, integer, numeric, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pJournalNumber ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pNotes ALIAS FOR $5;
  pCreditid ALIAS FOR $6;
  pDebitid ALIAS FOR $7;
  pMiscid ALIAS FOR $8;
  pAmount ALIAS FOR $9;
  pDistDate ALIAS FOR $10;
  _return INTEGER;

BEGIN

  SELECT insertGLTransaction( pJournalNumber, pSource, pDocType, pDocNumber, pNotes,
                              pCreditid, pDebitid, pMiscid, pAmount, pDistDate, TRUE) INTO _return;

  RETURN _return;

END;

Function: public.insertgltransaction(integer, text, text, text, text, integer, integer, integer, numeric, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pJournalNumber ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pNotes ALIAS FOR $5;
  pCreditid ALIAS FOR $6;
  pDebitid ALIAS FOR $7;
  pMiscid ALIAS FOR $8;
  pAmount ALIAS FOR $9;
  pDistDate ALIAS FOR $10;
  pPostTrialBal ALIAS FOR $11;
  
  _return INTEGER;

BEGIN

  SELECT insertGLTransaction( pJournalNumber, pSource, pDocType, pDocNumber, pNotes,
                              pCreditid, pDebitid, pMiscid, pAmount, pDistDate, pPostTrialBal, false) INTO _return;

  RETURN _return;

END;

Function: public.insertgltransaction(integer, text, text, text, text, integer, integer, integer, numeric, date, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pJournalNumber ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pNotes ALIAS FOR $5;
  pCreditid ALIAS FOR $6;
  pDebitid ALIAS FOR $7;
  pMiscid ALIAS FOR $8;
  pAmount ALIAS FOR $9;
  pDistDate ALIAS FOR $10;
  pPostTrialBal ALIAS FOR $11;
  pOnlyGL ALIAS FOR $12;
  _debitid INTEGER;
  _creditid INTEGER;
  _sequence INTEGER;
  _check INTEGER;

BEGIN

--  Check GL Interface metric
  IF (fetchMetricBool('InterfaceToGL') = false AND pSource IN ('I/M', 'P/D', 'S/R', 'W/O')) THEN
    RETURN 0;
  END IF;
  IF (fetchMetricBool('InterfaceAPToGL') = false AND pSource = 'A/P') THEN
    RETURN 0;
  END IF;
  IF (fetchMetricBool('InterfaceARToGL') = false AND pSource IN ('A/R', 'S/O', 'S/R')) THEN
    RETURN 0;
  END IF;

--  Is there anything to post?
--  ToDo - 2 should really be the scale of the base currency
  IF (round(pAmount, 2) = 0) THEN
    RETURN -3;
  END IF;

/*  Make sure we don't create an imbalance across companies.
    The 'IgnoreCompanyBalance' metric is a back door mechanism to
    allow legacy users to create transactions accross companies if
    they have been using the company segment for something else
    and they MUST continue to be able to do so.  It can only be 
    implemented by direct sql update to the metric table and should 
    otherwise be discouraged.
*/ 
  IF (COALESCE(fetchMetricValue('GLCompanySize'),0) > 0 
    AND fetchMetricBool('IgnoreCompany') = false)  THEN

    IF (SELECT (COALESCE(d.accnt_company,'') != COALESCE(c.accnt_company,''))
       FROM accnt d, accnt c
       WHERE ((d.accnt_id=pDebitid)
        AND (c.accnt_id=pCreditid))) THEN
      RAISE EXCEPTION 'G/L Transaction can not be posted because accounts % and % reference two differnt companies.',
        formatGlaccount(pDebitid), formatGlaccount(pCreditid);
    END IF;
  END IF;

--  Validate pDebitid
  IF (pDebitid IN (SELECT accnt_id FROM accnt)) THEN
    _debitid := pDebitid;
  ELSE
    SELECT getUnassignedAccntId() INTO _debitid;
  END IF;

--  Validate pCreditid
  IF (pCreditid IN (SELECT accnt_id FROM accnt)) THEN
    _creditid := pCreditid;
  ELSE
    SELECT getUnassignedAccntId() INTO _creditid;
  END IF;

-- refuse to accept postings into closed periods
  IF (SELECT BOOL_AND(COALESCE(period_closed, FALSE))
      FROM accnt LEFT OUTER JOIN
           period ON (pDistDate BETWEEN period_start AND period_end)
      WHERE (accnt_id IN (_creditid, _debitid))) THEN
    RAISE EXCEPTION 'Cannot post to closed period (%).', pDistDate;
    RETURN -4;  -- remove raise exception when all callers check return code
  END IF;

-- refuse to accept postings into frozen periods without proper priv
  IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
             BOOL_AND(COALESCE(period_freeze, FALSE))
      FROM accnt LEFT OUTER JOIN
           period ON (pDistDate BETWEEN period_start AND period_end)
      WHERE (accnt_id IN (_creditid, _debitid))) THEN
    RAISE EXCEPTION 'Cannot post to frozen period (%).', pDistDate;
    RETURN -4;  -- remove raise exception when all callers check return code
  END IF;

-- refuse to accept postings into nonexistent periods
  IF NOT EXISTS(SELECT period_id
                FROM period
                WHERE (pDistDate BETWEEN period_start AND period_end)) THEN
    RAISE EXCEPTION 'Cannot post to nonexistent period (%).', pDistDate;
  END IF;

--  Grab a sequence for the pair
  SELECT fetchGLSequence() INTO _sequence;

  IF (NOT pOnlyGL AND fetchMetricBool('UseJournals')) THEN
  --  First the credit	
    INSERT INTO sltrans
    ( sltrans_journalnumber, sltrans_posted, sltrans_created, sltrans_date,
      sltrans_sequence, sltrans_accnt_id, sltrans_source,
      sltrans_doctype, sltrans_docnumber, sltrans_notes,
      sltrans_misc_id, sltrans_amount )
    VALUES
    ( pJournalNumber, FALSE, CURRENT_TIMESTAMP, pDistDate,
      _sequence, _creditid, pSource,
      pDocType, pDocNumber, pNotes,
      pMiscid, pAmount );

  --  Now the debit
    INSERT INTO sltrans
    ( sltrans_journalnumber, sltrans_posted, sltrans_created, sltrans_date,
      sltrans_sequence, sltrans_accnt_id, sltrans_source,
      sltrans_doctype, sltrans_docnumber, sltrans_notes,
      sltrans_misc_id, sltrans_amount )
    VALUES
    ( pJournalNumber, FALSE, CURRENT_TIMESTAMP, pDistDate,
      _sequence, _debitid, pSource,
      pDocType, pDocNumber, pNotes,
      pMiscid, (pAmount * -1) );
  ELSE
  --  First the credit
    INSERT INTO gltrans
    ( gltrans_journalnumber, gltrans_posted, gltrans_exported, gltrans_created, gltrans_date,
      gltrans_sequence, gltrans_accnt_id, gltrans_source,
      gltrans_doctype, gltrans_docnumber, gltrans_notes,
      gltrans_misc_id, gltrans_amount )
    VALUES
    ( pJournalNumber, FALSE, FALSE, CURRENT_TIMESTAMP, pDistDate,
      _sequence, _creditid, pSource,
      pDocType, pDocNumber, pNotes,
      pMiscid, pAmount );

  --  Now the debit
    INSERT INTO gltrans
    ( gltrans_journalnumber, gltrans_posted, gltrans_exported, gltrans_created, gltrans_date,
      gltrans_sequence, gltrans_accnt_id, gltrans_source,
      gltrans_doctype, gltrans_docnumber, gltrans_notes,
      gltrans_misc_id, gltrans_amount )
    VALUES
    ( pJournalNumber, FALSE, FALSE, CURRENT_TIMESTAMP, pDistDate,
      _sequence, _debitid, pSource,
      pDocType, pDocNumber, pNotes,
      pMiscid, (pAmount * -1) );

    IF (pPostTrialBal) THEN
      PERFORM postIntoTrialBalance(_sequence);
    END IF;
  END IF;

  RETURN _sequence;

END;

Function: public.insertgltransaction(text, text, text, text, integer, integer, integer, numeric, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource ALIAS FOR $1;
  pDocType ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pNotes ALIAS FOR $4;
  pCreditid ALIAS FOR $5;
  pDebitid ALIAS FOR $6;
  pMiscid ALIAS FOR $7;
  pAmount ALIAS FOR $8;
  pDistDate ALIAS FOR $9;
  _return INTEGER;

BEGIN

  SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
                              pSource, pDocType, pDocNumber, pNotes,
                              pCreditid, pDebitid, pMiscid, pAmount, pDistDate) INTO _return;

  RETURN _return;

END;

Function: public.insertgltransaction(text, text, text, text, integer, integer, integer, numeric, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource ALIAS FOR $1;
  pDocType ALIAS FOR $2;
  pDocNumber ALIAS FOR $3;
  pNotes ALIAS FOR $4;
  pCreditid ALIAS FOR $5;
  pDebitid ALIAS FOR $6;
  pMiscid ALIAS FOR $7;
  pAmount ALIAS FOR $8;
  pDistDate ALIAS FOR $9;
  pPostTrialBal ALIAS FOR $10;
  _return INTEGER;

BEGIN

  SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
                              pSource, pDocType, pDocNumber, pNotes,
                              pCreditid, pDebitid, pMiscid, pAmount, pDistDate, pPostTrialBal) INTO _return;

  RETURN _return;

END;

Function: public.insertintoglseries(integer, text, text, text, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pAccntid ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  _returnValue INTEGER;

BEGIN

  SELECT insertIntoGLSeries( pSequence, pSource, pDocType, pDocNumber,
                             pAccntid, pAmount, CURRENT_DATE, '' ) INTO _returnValue;

  RETURN _returnValue;

END;

Function: public.insertintoglseries(integer, text, text, text, integer, numeric, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pAccntid ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pDistDate ALIAS FOR $7;
  _returnValue INTEGER;

BEGIN

  SELECT insertIntoGLSeries( pSequence, pSource, pDocType, pDocNumber,
                             pAccntid, pAmount, pDistDate, '' ) INTO _returnValue;

  RETURN _returnValue;

END;

Function: public.insertintoglseries(integer, text, text, text, integer, numeric, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pAccntid ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pDistDate ALIAS FOR $7;
  pNotes ALIAS FOR $8;
  _returnValue INTEGER;

BEGIN

  SELECT insertIntoGLSeries( pSequence, pSource, pDocType, pDocNumber,
                             pAccntid, pAmount, pDistDate, pNotes, NULL ) INTO _returnValue;

  RETURN _returnValue;

END;

Function: public.insertintoglseries(integer, text, text, text, integer, numeric, date, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pSource ALIAS FOR $2;
  pDocType ALIAS FOR $3;
  pDocNumber ALIAS FOR $4;
  pAccntid ALIAS FOR $5;
  pAmount ALIAS FOR $6;
  pDistDate ALIAS FOR $7;
  pNotes ALIAS FOR $8;
  pMiscid ALIAS FOR $9;
  _glseriesid INTEGER;

BEGIN

--  Check GL Interface metric
  IF (fetchMetricBool('InterfaceToGL') = false AND pSource IN ('I/M', 'P/D', 'S/R', 'W/O')) THEN
    RETURN 0;
  END IF;
  IF (fetchMetricBool('InterfaceAPToGL') = false AND pSource = 'A/P') THEN
    RETURN 0;
  END IF;
  IF (fetchMetricBool('InterfaceARToGL') = false AND pSource IN ('A/R', 'S/O', 'S/R')) THEN
    RETURN 0;
  END IF;

--  Verify the target accnt
  IF ( (pAccntid IS NULL) OR (pAccntid = -1) ) THEN
    RETURN -1;
  END IF;

-- refuse to accept postings into closed periods
  IF (SELECT BOOL_AND(COALESCE(period_closed, FALSE))
      FROM accnt LEFT OUTER JOIN
           period ON (pDistDate BETWEEN period_start AND period_end)
      WHERE (accnt_id = pAccntid)) THEN
    RAISE EXCEPTION 'Cannot post to closed period (%).', pDistDate;
    RETURN -4;  -- remove raise exception when all callers check return code
  END IF;

-- refuse to accept postings into frozen periods without proper priv
  IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
             BOOL_AND(COALESCE(period_freeze, FALSE))
      FROM accnt LEFT OUTER JOIN
           period ON (pDistDate BETWEEN period_start AND period_end)
      WHERE (accnt_id = pAccntid)) THEN
    RAISE EXCEPTION 'Cannot post to frozen period (%).', pDistDate;
    RETURN -4;  -- remove raise exception when all callers check return code
  END IF;

-- refuse to accept postings into nonexistent periods
  IF NOT EXISTS(SELECT period_id
                FROM period
                WHERE (pDistDate BETWEEN period_start AND period_end)) THEN
    RAISE EXCEPTION 'Cannot post to nonexistent period (%).', pDistDate;
  END IF;

-- Insert into the glseries
  SELECT NEXTVAL('glseries_glseries_id_seq') INTO _glseriesid;
  INSERT INTO glseries
  ( glseries_id, glseries_sequence, glseries_source, glseries_doctype, glseries_docnumber,
    glseries_accnt_id, glseries_amount, glseries_distdate, glseries_notes, glseries_misc_id )
  VALUES
  ( _glseriesid, pSequence, pSource, pDocType, pDocNumber,
    pAccntid, pAmount, pDistDate, pNotes, pMiscid );

  RETURN _glseriesid;

END;

Function: public.insertinvoice(api.invoice)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
	pNew ALIAS FOR $1;
BEGIN
	-- NOTE: (SELECT getCustId(...)) seems redundant, but it actually produces
	-- a HUGE performance increase because it makes the Postgres query planner
	-- use an index scan rather than an sequential table scan on cust_id
	INSERT INTO invchead (
		invchead_invcnumber,
		invchead_ordernumber,
		invchead_invcdate,
		invchead_shipdate,
		invchead_orderdate,
		invchead_printed,
		invchead_posted,
		invchead_salesrep_id,
		invchead_commission,
		invchead_taxzone_id,
		invchead_terms_id,
		invchead_cust_id,
		invchead_billto_name,
		invchead_billto_address1,
		invchead_billto_address2,
		invchead_billto_address3,
		invchead_billto_city,
		invchead_billto_state,
		invchead_billto_zipcode,
		invchead_billto_country,
		invchead_billto_phone,
		invchead_shipto_id,
		invchead_shipto_name,
		invchead_shipto_address1,
		invchead_shipto_address2,
		invchead_shipto_address3,
		invchead_shipto_city,
		invchead_shipto_state,
		invchead_shipto_zipcode,
		invchead_shipto_country,
		invchead_shipto_phone,
		invchead_ponumber,
		invchead_shipvia,
		invchead_prj_id,
		invchead_fob,
		invchead_misc_descrip,
		invchead_misc_amount,
		invchead_misc_accnt_id,
		invchead_freight,
		invchead_curr_id,
		invchead_payment,
		invchead_notes,
                invchead_saletype_id,
                invchead_shipzone_id
	) SELECT
		(CASE -- use a case here so we don't unnecessarily fetch a new invoice number
			WHEN pNew.invoice_number IS NULL THEN CAST(fetchInvcNumber() AS TEXT)
			WHEN pNew.invoice_number = '' THEN CAST(fetchInvcNumber() AS TEXT)
			ELSE pNew.invoice_number
		END),
		pNew.order_number,
		COALESCE(pNew.invoice_date, CURRENT_DATE),
		pNew.ship_date,
		pNew.order_date,
		FALSE,
		FALSE,
		COALESCE(getSalesRepId(pNew.sales_rep),shipto_salesrep_id,cust_salesrep_id),
		COALESCE(pNew.commission, 0),
		CASE
			WHEN pNew.tax_zone = 'None' THEN NULL
			ELSE COALESCE(getTaxZoneId(pNew.tax_zone),shipto_taxzone_id,cust_taxzone_id)
		END,
		COALESCE(getTermsId(pNew.terms),cust_terms_id),
		(SELECT getCustId(pNew.customer_number)),
		COALESCE(pNew.billto_name, cohead_billtoname, cust_name),
		COALESCE(pNew.billto_address1, cohead_billtoaddress1, addr_line1),
		COALESCE(pNew.billto_address2, cohead_billtoaddress2, addr_line2),
		COALESCE(pNew.billto_address3, cohead_billtoaddress3, addr_line3),
		COALESCE(pNew.billto_city, cohead_billtocity, addr_city),
		COALESCE(pNew.billto_state, cohead_billtostate, addr_state),
		COALESCE(pNew.billto_postal_code, cohead_billtozipcode, addr_postalcode),
		COALESCE(pNew.billto_country, cohead_billtocountry, addr_country),
		COALESCE(pNew.billto_phone, ''),
		COALESCE(shipto_id,-1),
		pNew.shipto_name,
		pNew.shipto_address1,
		pNew.shipto_address2,
		pNew.shipto_address3,
		pNew.shipto_city,
		pNew.shipto_state,
		pNew.shipto_postal_code,
		pNew.shipto_country,
		pNew.shipto_phone,
		COALESCE(pNew.po_number, ''),
		COALESCE(pNew.ship_via,shipto_shipvia,cust_shipvia),
		COALESCE(getPrjId(pNew.project_number),-1),
		COALESCE(pNew.fob,fetchDefaultFob((
			SELECT CAST(usrpref_value AS INTEGER) 
			FROM usrpref, whsinfo
			WHERE ((warehous_id=CAST(usrpref_value AS INTEGER))
				AND (warehous_shipping)
				AND (warehous_active)
				AND (usrpref_username=getEffectiveXtUser())
				AND (usrpref_name='PreferredWarehouse')
			)
		))),
		pNew.misc_charge_description,
		COALESCE(pNew.misc_charge, 0),
		COALESCE(getGlAccntId(pNew.misc_charge_account_number),-1),
		COALESCE(pNew.freight, 0),
		COALESCE(getCurrId(pNew.currency),(
			SELECT cust_curr_id
			FROM custinfo
			WHERE (cust_id=(SELECT getCustId(pNew.customer_number)))
		),basecurrid()),
		COALESCE(pNew.payment,0),
		COALESCE(pNew.notes,''),
                getSaleTypeId(pNew.sale_type),
                getShipZoneId(pNew.shipto_shipzone)
	FROM custinfo
		LEFT OUTER JOIN shiptoinfo ON (shipto_id=(SELECT CASE
			WHEN getShiptoId(pNew.customer_number,pNew.shipto_number) IS NOT NULL
				THEN getShiptoId(pNew.customer_number,pNew.shipto_number)
			ELSE (SELECT shipto_id FROM shiptoinfo WHERE shipto_cust_id=cust_id AND shipto_default)
		END))
               LEFT OUTER JOIN cohead ON (cohead_number=pNEW.order_number)
               LEFT OUTER JOIN cntct ON (cntct_id=cust_cntct_id)
               LEFT OUTER JOIN addr ON (addr_id=cntct_addr_id)
	WHERE cust_id = (SELECT getCustId(pNew.customer_number));
	RETURN TRUE;
END;

Function: public.insertinvoicelineitem(api.invoiceline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
	pNew ALIAS FOR $1;
	_r RECORD;
BEGIN
	INSERT INTO invcitem (
		invcitem_invchead_id,
		invcitem_linenumber,
		invcitem_item_id,
		invcitem_warehous_id,
		invcitem_custpn,
		invcitem_number,
		invcitem_descrip,
		invcitem_ordered,
		invcitem_billed,
                invcitem_updateinv,
		invcitem_custprice,
		invcitem_price,
		invcitem_notes,
		invcitem_salescat_id,
		invcitem_taxtype_id,
		invcitem_qty_uom_id,
		invcitem_qty_invuomratio,
		invcitem_price_uom_id,
		invcitem_price_invuomratio,
                invcitem_rev_accnt_id
	) SELECT
		invchead_id,
		COALESCE(pNew.line_number,(
			SELECT (COALESCE(MAX(invcitem_linenumber), 0) + 1)
			FROM invcitem WHERE (invcitem_invchead_id=invchead_id)
		)),
		COALESCE(item_id, -1),
		COALESCE(getwarehousid(pNew.site,'ALL'),-1),
		pNew.customer_part_number,
		(CASE WHEN item_id IS NULL THEN pNew.misc_item_number ELSE NULL END),
		(CASE WHEN item_id IS NULL THEN pNew.misc_item_description ELSE NULL END),
		pNew.qty_ordered,
		COALESCE(pNew.qty_billed, 0),
                COALESCE(pNew.update_inventory,FALSE),
		0, -- invcitem_custprice
		COALESCE(pNew.net_unit_price,itemPrice(item_id,invchead_cust_id,
			invchead_shipto_id,pNew.qty_ordered,invchead_curr_id,invchead_orderdate)),
		COALESCE(pNew.notes,''),
		CASE
			WHEN item_id IS NULL THEN
				(SELECT salescat_id FROM salescat WHERE salescat_name = pNew.sales_category)
			ELSE NULL
		END,
		taxtype_id,
		CASE
			WHEN item_id IS NOT NULL THEN
				COALESCE((SELECT uom_id FROM uom WHERE (uom_name=pNew.qty_uom)), item_price_uom_id)
			ELSE NULL
		END,
		CASE
			WHEN item_id IS NOT NULL THEN
				itemuomtouomratio(item_id,
					COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.qty_uom),item_price_uom_id),
					item_price_uom_id
				)
			ELSE 1
		END,
		CASE
			WHEN item_id IS NOT NULL THEN
				COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.price_uom),item_price_uom_id)
			ELSE NULL
		END,
		CASE
			WHEN item_id IS NOT NULL THEN
				itemuomtouomratio(item_id,
					COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.price_uom),item_price_uom_id),
					item_price_uom_id
				)
			ELSE 1
		END,
                getGlAccntId(pNew.alternate_rev_account)
	FROM invchead
		LEFT OUTER JOIN item ON (item_id=getItemId(pNew.item_number))
		LEFT OUTER JOIN taxtype ON (taxtype_id=CASE
			WHEN pNew.tax_type IS NULL THEN getItemTaxType(item_id,invchead_taxzone_id)
			WHEN pNew.tax_type = 'None' THEN NULL
			ELSE (SELECT taxtype_id FROM taxtype WHERE taxtype_name=pNew.tax_type)
		END)
	WHERE (invchead_invcnumber=pNew.invoice_number) AND (invchead_posted=FALSE);
	RETURN TRUE;
END;

Function: public.insertitemcost(integer, integer, integer, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pItemId ALIAS FOR $1;
pCostElemId ALIAS FOR $2;
pCurrId ALIAS FOR $3;
pCost ALIAS FOR $4;
pPostToStandard ALIAS FOR $5;
_itemcost_id INTEGER;
_update_return INTEGER;
_postcost_return BOOLEAN;

--This function is used with the api.itemcost View for updating and inserting
--into the itemcosts table

BEGIN
  IF (pCost IS NULL OR pCost < 0) THEN
    RAISE EXCEPTION 'itemcost Actual Cost Invalid ', pCost;
  END IF;

-- Check for uniqueness
  SELECT itemcost_id INTO _itemcost_id
  FROM itemcost
  WHERE ( (itemcost_item_id = pItemId)
    AND   (itemcost_costelem_id = pCostElemId)
    AND   (NOT itemcost_lowlevel) );
  IF (FOUND) THEN
    RAISE EXCEPTION 'itemcost already exists for this Item and Cost Element';
  END IF;

-- Check for valid combination of item_type and costelem_type
  IF (SELECT (COUNT(*) > 0)
      FROM item, costelem
      WHERE (item_id=pItemId)
        AND (costelem_id=pCostElemId)
        AND (item_type IN ('M', 'F', 'B', 'C', 'T'))
        AND (costelem_type IN ('Material'))) THEN
    RAISE EXCEPTION 'itemcost of this type is invalid for Manufactured Item';
  END IF;
  
  IF (SELECT (COUNT(*) > 0)
      FROM item, costelem
      WHERE (item_id=pItemId)
        AND (costelem_id=pCostElemId)
        AND (item_type IN ('O', 'P'))
        AND (costelem_type IN ('Direct Labor', 'Overhead', 'Machine Overhead'))) THEN
    RAISE EXCEPTION 'itemcost of this type is invalid for Purchased Item';
  END IF;
  
  IF (pCost > 0) THEN
    SELECT NEXTVAL('itemcost_itemcost_id_seq') INTO _itemcost_id;
    INSERT INTO itemcost
      ( itemcost_id, itemcost_item_id, itemcost_costelem_id, itemcost_lowlevel,
        itemcost_stdcost, itemcost_posted, itemcost_actcost, itemcost_updated, itemcost_curr_id )
    VALUES
      ( _itemcost_id, pItemId, pCostElemId, FALSE,
        0, startOfTime(), pCost, CURRENT_DATE, pCurrId );

    --Only Post Cost to standard if the parameter is set to true
    IF (pPostToStandard) THEN
      IF (NOT checkPrivilege('PostStandardCosts')) THEN
        RAISE EXCEPTION 'You do not have privileges to poststandard itemcosts. Set api.itemcost post_to_standard to false';
      END IF;
      SELECT postcost(_itemcost_id) INTO _postcost_return;       
      IF (NOT _postcost_return) THEN
        RETURN -2;
      END IF;
    END IF;
  ELSE 
    RETURN -1;
  END IF;

  RETURN _itemcost_id;
  
END;

Function: public.insertsalesline(api.salesline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNEW ALIAS FOR $1;
  _r RECORD;

BEGIN

  IF (NOT EXISTS (SELECT cohead_id FROM cohead WHERE cohead_number=pNEW.order_number)) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed because Sales Order % not found', pNEW.order_number;
  END IF;

  IF (NOT EXISTS (SELECT item_id FROM item WHERE item_number=pNEW.item_number)) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed because Item Number % not found', pNEW.item_number;
  END IF;

  SELECT * INTO _r
  FROM cohead, itemsite, item, whsinfo
  WHERE ((cohead_number=pNEW.order_number)
  AND (itemsite_warehous_id=warehous_id
  AND (itemsite_item_id=item_id)
  AND (itemsite_active)
  AND (item_number=pNEW.item_number)
  AND (warehous_active)
  AND (warehous_id=COALESCE(getWarehousId(pNEW.sold_from_site,'ALL'),cohead_warehous_id,fetchprefwarehousid()))));

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Function insertSalesLine failed with unknown failure to retrieve Sales Order';
  END IF;

  INSERT INTO coitem (
    coitem_cohead_id,
    coitem_linenumber,
    coitem_itemsite_id,
    coitem_status,
    coitem_scheddate,
    coitem_promdate,
    coitem_qtyord,
    coitem_qty_uom_id,
    coitem_qty_invuomratio,
    coitem_qtyshipped,
    coitem_unitcost,
    coitem_price,
    coitem_price_uom_id,
    coitem_price_invuomratio,
    coitem_custprice,
    coitem_order_id,
    coitem_memo,
    coitem_imported,
    coitem_qtyreturned,
    coitem_custpn,
    coitem_order_type,
    coitem_substitute_item_id,
    coitem_prcost,
    coitem_taxtype_id,
    coitem_warranty,
    coitem_cos_accnt_id,
    coitem_rev_accnt_id)
  VALUES (
    _r.cohead_id,
    pNEW.line_number::INTEGER,
    _r.itemsite_id,
    pNEW.status,
    pNEW.scheduled_date,
    pNEW.promise_date,
    pNEW.qty_ordered,
    COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),
    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.qty_uom),_r.item_inv_uom_id),_r.item_inv_uom_id),
    0,
    stdCost(_r.item_id),
    COALESCE(pNEW.net_unit_price,itemPrice(_r.item_id,_r.cohead_cust_id,
             _r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate)),
    COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),
    itemuomtouomratio(_r.item_id,COALESCE(getUomId(pNEW.price_uom),_r.item_price_uom_id),_r.item_price_uom_id),
    itemPrice(_r.item_id,_r.cohead_cust_id,_r.cohead_shipto_id,pNEW.qty_ordered,_r.cohead_curr_id,_r.cohead_orderdate),
    -1,
    pNEW.notes,
    true,
    0,
    pNEW.customer_pn,
    CASE
      WHEN ((pNEW.create_order  AND (_r.item_type = 'M')) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createwo)) THEN
        'W'
      WHEN ((pNEW.create_order AND (_r.item_type = 'P')) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopr)) THEN
        'R'
      WHEN ((pNEW.create_order AND (_r.item_type = 'P') AND (_r.itemsite_createsopo)) OR 
           ((pNEW.create_order IS NULL) AND _r.itemsite_createsopo)) THEN
        'P'
    END,
    getitemid(pNEW.substitute_for),
    pNEW.overwrite_po_price,
    COALESCE(getTaxTypeId(pNEW.tax_type), getItemTaxType(_r.itemsite_item_id, _r.cohead_taxzone_id)),
    pNEW.warranty,
    getGlAccntId(pNEW.alternate_cos_account),
    getGlAccntId(pNEW.alternate_rev_account)
    );

  RETURN TRUE;
END;

Function: public.intervaltominutes(interval)

Returns: numeric

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT (EXTRACT(DAY FROM $1) * 24 * 60 +
          EXTRACT(HOUR FROM $1) * 60 +
          EXTRACT(MINUTE FROM $1) +
          ROUND((EXTRACT(SECOND FROM $1) / 60)::NUMERIC, 4))::NUMERIC AS result

Function: public.invadjustment(integer, numeric, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invAdjustment($1, $2, $3, $4, CURRENT_TIMESTAMP, NULL);
END;

Function: public.invadjustment(integer, numeric, text, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invAdjustment($1, $2, $3, $4, $5, NULL);
END;

Function: public.invadjustment(integer, numeric, text, text, timestamp with time zone, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid     ALIAS FOR $1;
  pQty            ALIAS FOR $2;
  pDocumentNumber ALIAS FOR $3;
  pComments       ALIAS FOR $4;
  pGlDistTS       ALIAS FOR $5;
  pCostValue      ALIAS FOR $6;
  _invhistid      INTEGER;
  _itemlocSeries  INTEGER;

BEGIN

--  Make sure the passed itemsite points to a real item
  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  SELECT postInvTrans( itemsite_id, 'AD', pQty,
                       'I/M', 'AD', pDocumentNumber, '',
                       ('Miscellaneous Adjustment for item ' || item_number || E'\n' ||  pComments),
                       costcat_asset_accnt_id, costcat_adjustment_accnt_id,
                       _itemlocSeries, pGlDistTS, pCostValue) INTO _invhistid
  FROM itemsite, item, costcat
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (itemsite_id=pItemsiteid) );

  RETURN _itemlocSeries;

END;

Function: public.invexpense(pprjid integer, pgldistts numeric, pcomments integer, pdocumentnumber text, pexpcatid text, pqty timestamp with time zone, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _invhistid INTEGER;
  _itemlocSeries INTEGER;

BEGIN

  --  Make sure the passed itemsite points to a real item
  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  SELECT postInvTrans( itemsite_id, 'EX', pQty,
                       'I/M', 'EX', pDocumentNumber, '',
                       CASE WHEN (pQty < 0) THEN ('Reverse Material Expense for item ' || item_number || E'\n' ||  pComments)
                            ELSE  ('Material Expense for item ' || item_number || E'\n' ||  pComments)
                       END,
                       getPrjAccntId(pPrjid, expcat_exp_accnt_id), costcat_asset_accnt_id,
                       _itemlocSeries, pGlDistTS) INTO _invhistid
  FROM itemsite, item, costcat, expcat
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (itemsite_id=pItemsiteid)
   AND (expcat_id=pExpcatid) );

  INSERT INTO invhistexpcat (invhistexpcat_invhist_id, invhistexpcat_expcat_id)
                     VALUES (_invhistid,               pExpcatid);

  RETURN _itemlocSeries;

END;

Function: public.invhistsense(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvhistId ALIAS FOR $1;
  _count INTEGER;
  _row RECORD;
  _sense INTEGER;
BEGIN

  SELECT invhist_transtype, invhist_ordnumber, itemsite_warehous_id
  INTO _row 
  FROM invhist 
    JOIN itemsite ON (itemsite_id=invhist_itemsite_id)
  WHERE (invhist_id=pInvhistId);

  GET DIAGNOSTICS _count = ROW_COUNT;
  IF (_count = 0) THEN
    RAISE EXCEPTION 'Record not found for invhist_id=%',pInvhistId;
  END IF;
  
  -- increase inventory: AD RM RT RP RR RS RX RB TR
  -- decrease inventory: IM IB IT SH SI EX RI
  -- TS and TR are special: shipShipment and recallShipment should not change
  -- QOH at the Transfer Order src whs (as this was done by issueToShipping)
  -- but postReceipt should change QOH at the transit whs
  IF (_row.invhist_transtype='TS') THEN
       _sense := CASE WHEN (SELECT tohead_trns_warehous_id=_row.itemsite_warehous_id
                                  FROM tohead
                                  WHERE (tohead_number=_row.invhist_ordnumber)) THEN -1
                ELSE 0
                END;
  ELSIF (_row.invhist_transtype='TR') THEN
      _sense := CASE WHEN (SELECT tohead_src_warehous_id=_row.itemsite_warehous_id
                                  FROM tohead
                                  WHERE (tohead_number=_row.invhist_ordnumber)) THEN 0
                ELSE 1
                END;
  ELSIF (_row.invhist_transtype IN ('IM', 'IB', 'IT', 'SH', 'SI', 'EX', 'RI')) THEN
      _sense := -1;
    ELSE
      _sense := 1;
    END IF;

  RETURN _sense;
END;

Function: public.invhisttrig()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

--  Need to allow 'temporary' negative for average costed item that has been frozen.
--  Check at itemsite after all of the transactions have been thawed will ensure
--  that final Qty On Hand is positive. 
--  IF (NEW.invhist_qoh_after < 0 AND NEW.invhist_costmethod = 'A') THEN
--    RAISE EXCEPTION 'Invhist (%) is recording with average costing and is not allowed to have a negative quantity on hand.', NEW.invhist_id;
--  END IF;

  IF ( ( SELECT itemsite_freeze
         FROM itemsite
         WHERE (itemsite_id=NEW.invhist_itemsite_id) ) ) THEN
    NEW.invhist_posted = FALSE;
  END IF;

  -- never change the created timestamp, which defaults to CURRENT_TIMESTAMP
  IF (TG_OP != 'INSERT') THEN
    NEW.invhist_created = OLD.invhist_created;
  ELSE
    -- Always need a series id for distribution posting
    IF (NEW.invhist_series IS NULL) THEN
      RAISE EXCEPTION 'Column invhist_series may not be null.';
    END IF;
  END IF;

  RETURN NEW;

END;

Function: public.invoicetotal(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvoiceId ALIAS FOR $1;
  _linesum   NUMERIC;
  _linetax   NUMERIC;
  _result    NUMERIC;
  _allocated NUMERIC;
  _posted    BOOLEAN;

BEGIN

  SELECT SUM(ROUND(COALESCE((invcitem_billed * invcitem_qty_invuomratio) *
                             (invcitem_price / COALESCE(invcitem_price_invuomratio,1)), 0),2))
                          INTO _linesum
  FROM invcitem
  WHERE (invcitem_invchead_id=pInvoiceId);

  -- TODO: why sum on the result of select round(sum(), 2)?
  SELECT SUM(tax) INTO _linetax
    FROM (SELECT ROUND(SUM(COALESCE(taxdetail_tax, 0)),2) AS tax 
            FROM tax 
            JOIN calculateTaxDetailSummary('I', pInvoiceId, 'T') ON (taxdetail_tax_id=tax_id)
	  GROUP BY tax_id) AS data;

  SELECT noNeg(invchead_freight + invchead_misc_amount + COALESCE(_linetax, 0) + COALESCE(_linesum, 0)),
         invchead_posted INTO _result, _posted
  FROM invchead
  WHERE (invchead_id=pInvoiceId);

  IF NOT FOUND THEN
    RETURN 0;
  END IF;

  IF (_posted) THEN
    SELECT COALESCE(SUM(currToCurr(arapply_curr_id, aropen_curr_id,
                                   arapply_applied, aropen_docdate)),0) INTO _allocated
     FROM arapply, aropen, invchead
    WHERE ( (invchead_posted)
      AND   (invchead_id=pInvoiceId)
      AND   (aropen_docnumber=invchead_invcnumber)
      AND   (aropen_doctype='I')
      AND   (arapply_target_aropen_id=aropen_id)
      AND   (arapply_reftype='S')
      AND   (invchead_posted) ) ;
  ELSE
    SELECT COALESCE(SUM(CASE WHEN((aropen_amount - aropen_paid) >=
                       currToCurr(aropenalloc_curr_id, aropen_curr_id,
                          aropenalloc_amount, aropen_docdate))
           THEN currToCurr(aropenalloc_curr_id, invchead_curr_id,
                   aropenalloc_amount, aropen_docdate)
           ELSE currToCurr(aropen_curr_id, invchead_curr_id,
                   aropen_amount - aropen_paid, aropen_docdate)
           END),0) INTO _allocated
     FROM invchead LEFT OUTER JOIN cohead ON (cohead_number=invchead_ordernumber)
                   JOIN aropenalloc ON ((aropenalloc_doctype='I' AND aropenalloc_doc_id=invchead_id) OR
                                        (aropenalloc_doctype='S' AND aropenalloc_doc_id=cohead_id))
                   JOIN aropen ON (aropen_id=aropenalloc_aropen_id AND (aropen_amount - aropen_paid) > 0.0)
    WHERE ( (NOT invchead_posted)
      AND   (invchead_id=pInvoiceId) );
  END IF;
  
  RETURN _result - COALESCE(_allocated, 0);

END;

Function: public.invreceipt(integer, numeric, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invReceipt($1, $2, $3, $4, $5, CURRENT_TIMESTAMP, NULL);
END;

Function: public.invreceipt(integer, numeric, text, text, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invReceipt($1, $2, $3, $4, $5, $6, NULL);
END;

Function: public.invreceipt(integer, numeric, text, text, text, timestamp with time zone, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pOrdernumber ALIAS FOR $3;
  pDocumentNumber ALIAS FOR $4;
  pComments ALIAS FOR $5;
  pGlDistTS     ALIAS FOR $6;
  pCostValue ALIAS FOR $7;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;

BEGIN

--  Make sure the passed itemsite points to a real item
  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  SELECT postInvTrans( itemsite_id, 'RX', pQty,
                       'I/M', 'RX', pDocumentNumber, '',
                       ('Miscellaneous Receipt for item ' || item_number || E'\n' ||  pComments),
                       costcat_asset_accnt_id, costcat_liability_accnt_id,
                       _itemlocSeries, pGlDistTS, pCostValue) INTO _invhistid
  FROM itemsite, item, costcat
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (itemsite_id=pItemsiteid) );

  RETURN _itemlocSeries;

END;

Function: public.invscrap(integer, numeric, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invScrap($1, $2, $3, $4, CURRENT_TIMESTAMP);
END;

Function: public.invscrap(integer, numeric, text, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invScrap($1, $2, $3, $4, $5, NULL);
END;

Function: public.invscrap(integer, numeric, text, text, timestamp with time zone, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN invScrap($1, $2, $3, $4, $5, $6, NULL);
END;

Function: public.invscrap(integer, numeric, text, text, timestamp with time zone, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pDocumentNumber ALIAS FOR $3;
  pComments ALIAS FOR $4;
  pGlDistTS ALIAS FOR $5;
  pInvHistId ALIAS FOR $6;
  pPrjid ALIAS FOR $7;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;

BEGIN

--  Make sure the passed itemsite points to a real item
  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  IF (pInvHistId IS NOT NULL) THEN
    SELECT invhist_series INTO _itemlocSeries
    FROM invhist
    WHERE invhist_id=pInvHistId;
  ELSE
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  END IF;
  
  SELECT postInvTrans( itemsite_id, 'SI', pQty,
                       'I/M', 'SI', pDocumentNumber, '',
                       CASE WHEN (pQty < 0) THEN ('Reverse Material Scrap for item ' || item_number || E'\n' ||  pComments)
                            ELSE ('Material Scrap for item ' || item_number || E'\n' ||  pComments)
                       END,
                       getPrjAccntId(pPrjid, costcat_scrap_accnt_id), costcat_asset_accnt_id,
                       _itemlocSeries, pGlDistTS, NULL, pInvHistId) INTO _invhistid
  FROM itemsite, item, costcat
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (itemsite_id=pItemsiteid) );

  RETURN _itemlocSeries;

END;

Function: public.isdba(text)

Returns: boolean

Language: SQL

  SELECT (datdba=pg_roles.oid OR rolsuper) AS issuper
    FROM pg_database, pg_roles
  WHERE ((datname=current_database())
     AND (rolname=COALESCE($1, getEffectiveXtUser())));

Function: public.ismulticurr()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN (SELECT (count(*) > 1)
          FROM curr_symbol);
END;

Function: public.isnumeric(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pText ALIAS FOR $1;
  _cursor INTEGER;

BEGIN

  IF ( (LENGTH(pText) = 0) OR (pText IS NULL) ) THEN
    RETURN FALSE;
  END IF;

  FOR _cursor IN 1..LENGTH(pText) LOOP
    IF (SUBSTRING(pText FROM _cursor FOR 1) NOT IN ( '0', '1', '2', '3', '4',
                                                     '5' ,'6' ,'7' ,'8' ,'9' )) THEN
      RETURN FALSE;
    END IF;
  END LOOP;

  RETURN TRUE;

END;

Function: public.issueallbalancetoshipping(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueAllBalanceToShipping('SO', $1, 0, NULL);
END;

Function: public.issueallbalancetoshipping(text, integer, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  pheadid		ALIAS FOR $2;
  _itemlocSeries	INTEGER 		 := $3;
  _timestamp		TIMESTAMP WITH TIME ZONE := $4;
  _s			RECORD;

BEGIN
  IF (pordertype = 'SO') THEN
    FOR _s IN SELECT coitem_id,
		     noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned -
			   ( SELECT COALESCE(SUM(shipitem_qty), 0)
			     FROM shipitem, shiphead
			     WHERE ( (shipitem_orderitem_id=coitem_id)
			      AND (shipitem_shiphead_id=shiphead_id)
			      AND (NOT shiphead_shipped)
			      AND (shiphead_order_type=pordertype) ) ) ) AS balance
	      FROM coitem LEFT OUTER JOIN (itemsite JOIN item ON (itemsite_item_id=item_id)) ON (coitem_itemsite_id=itemsite_id)
	      WHERE ( (coitem_status NOT IN ('C','X'))
                AND (item_type != 'K')
	       AND (coitem_cohead_id=pheadid) ) LOOP

      IF (_s.balance <> 0) THEN
	_itemlocSeries := issueToShipping(pordertype, _s.coitem_id, _s.balance, _itemlocSeries, _timestamp);
	IF (_itemlocSeries < 0) THEN
	  EXIT;
	END IF;
      END IF;
    END LOOP;

  ELSEIF (pordertype = 'TO') THEN
    FOR _s IN SELECT toitem_id,
		     noNeg( toitem_qty_ordered - toitem_qty_shipped -
			   ( SELECT COALESCE(SUM(shipitem_qty), 0)
			     FROM shipitem, shiphead
			     WHERE ( (shipitem_orderitem_id=toitem_id)
			      AND (shipitem_shiphead_id=shiphead_id)
			      AND (NOT shiphead_shipped)
			      AND (shiphead_order_type=pordertype) ) ) ) AS balance
	      FROM toitem
	      WHERE ( (toitem_status NOT IN ('C','X'))
	       AND (toitem_tohead_id=pheadid) ) LOOP

      IF (_s.balance <> 0) THEN
	_itemlocSeries := issueToShipping(pordertype, _s.toitem_id, _s.balance, _itemlocSeries, _timestamp);
	IF (_itemlocSeries < 0) THEN
	  EXIT;
	END IF;
      END IF;
    END LOOP;

  ELSE
    RETURN -1;
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.issuelinebalancetoshipping(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueLineBalanceToShipping('SO', $1, NULL);
END;

Function: public.issuelinebalancetoshipping(text, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueLineBalanceToShipping($1, $2, $3, 0, NULL);
END;

Function: public.issuelinebalancetoshipping(text, integer, timestamp with time zone, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  pitemid		ALIAS FOR $2;
  ptimestamp		ALIAS FOR $3;
  pitemlocseries       	ALIAS FOR $4;
  pinvhistid		ALIAS FOR $5;
  _itemlocSeries	INTEGER := 0;
  _qty			NUMERIC;

BEGIN
  _itemlocSeries := COALESCE(pitemlocseries,0);
  
  IF (pordertype = 'SO') THEN
    SELECT noNeg( coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned - 
                ( SELECT COALESCE(SUM(shipitem_qty), 0)
                  FROM shipitem, shiphead
                  WHERE ((shipitem_orderitem_id=coitem_id)
                    AND  (shipitem_shiphead_id=shiphead_id)
                    AND  (NOT shiphead_shipped) ) ) ) INTO _qty
    FROM coitem
    WHERE (coitem_id=pitemid);
  ELSEIF (pordertype = 'TO') THEN
    SELECT noNeg( toitem_qty_ordered - toitem_qty_shipped - 
                ( SELECT COALESCE(SUM(shipitem_qty), 0)
                  FROM shipitem, shiphead
                  WHERE ( (shipitem_orderitem_id=toitem_id)
                   AND (shipitem_shiphead_id=shiphead_id)
                   AND (NOT shiphead_shipped) ) ) ) INTO _qty
    FROM toitem
    WHERE (toitem_id=pitemid);
  ELSE
    RETURN -1;
  END IF;

  IF (_qty > 0) THEN
    _itemlocSeries := issueToShipping(pordertype, pitemid, _qty, _itemlocSeries, ptimestamp, pinvhistid);
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.issues(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;

BEGIN
  IF (pTransType IN ('IM', 'IB', 'IT')) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.issuetoshipping(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueToShipping('SO', $1, $2, 0, CURRENT_TIMESTAMP);
END;

Function: public.issuetoshipping(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueToShipping('SO', $1, $2, $3, CURRENT_TIMESTAMP);
END;

Function: public.issuetoshipping(text, integer, numeric, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueToShipping($1, $2, $3, $4, $5, NULL);
END;

Function: public.issuetoshipping(text, integer, numeric, integer, timestamp with time zone, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  pitemid		ALIAS FOR $2;
  pQty			ALIAS FOR $3;
  _itemlocSeries	INTEGER	:= $4;
  _timestamp		TIMESTAMP WITH TIME ZONE := $5;
  pinvhistid		ALIAS FOR $6;
  _coholdtype		TEXT;
  _invhistid		INTEGER;
  _shipheadid		INTEGER;
  _shipnumber		INTEGER;
  _cntctid              INTEGER;
  _p                    RECORD;
  _m                    RECORD;
  _value                NUMERIC;
  _warehouseid		INTEGER;
  _shipitemid     	INTEGER;
  _freight              NUMERIC;

BEGIN

  IF (_timestamp IS NULL) THEN
    _timestamp := CURRENT_TIMESTAMP;
  END IF;

  IF (_itemlocSeries = 0) THEN
    _itemlocSeries := NEXTVAL('itemloc_series_seq');
  END IF;

  IF (pordertype = 'SO') THEN

    -- Check site security
    SELECT warehous_id INTO _warehouseid
    FROM coitem,itemsite,site()
    WHERE ((coitem_id=pitemid)
    AND (itemsite_id=coitem_itemsite_id)
    AND (warehous_id=itemsite_warehous_id));
          
    IF (NOT FOUND) THEN
      RETURN 0;
    END IF;

    -- Check for average cost items going negative
    IF ( SELECT ( (itemsite_costmethod='A') AND
                  ((itemsite_qtyonhand - round(pQty * coitem_qty_invuomratio, 6)) < 0.0) )
         FROM coitem JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
         WHERE (coitem_id=pitemid) ) THEN
      RETURN -20;
    END IF;

    -- Check auto registration
    IF ( SELECT COALESCE(itemsite_autoreg, FALSE)
         FROM coitem JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
         WHERE (coitem_id=pitemid) ) THEN
      SELECT COALESCE(crmacct_cntct_id_1, -1) INTO _cntctid
      FROM coitem JOIN cohead ON (cohead_id=coitem_cohead_id)
                  JOIN crmacct ON (crmacct_cust_id=cohead_cust_id)
      WHERE (coitem_id=pitemid);
      IF (_cntctid = -1) THEN
        RETURN -15;
      END IF;
    END IF; 
  
    SELECT shiphead_id INTO _shipheadid
    FROM shiphead, coitem
    WHERE ((shiphead_order_id=coitem_cohead_id)
      AND  (NOT shiphead_shipped)
      AND  (coitem_id=pitemid)
      AND  (shiphead_order_type=pordertype));
    IF (NOT FOUND) THEN
      SELECT NEXTVAL('shiphead_shiphead_id_seq') INTO _shipheadid;

      _shipnumber := fetchShipmentNumber();
      IF (_shipnumber < 0) THEN
	RETURN -10;
      END IF;

      SELECT cohead_holdtype INTO _coholdtype
      FROM cohead, coitem
      WHERE ((cohead_id=coitem_cohead_id)
        AND  (coitem_id=pitemid));

      IF (_coholdtype = 'C') THEN
	RETURN -12;
      ELSIF (_coholdtype = 'P') THEN
	RETURN -13;
      ELSIF (_coholdtype = 'R') THEN
	RETURN -14;
      END IF;

      INSERT INTO shiphead
      ( shiphead_id, shiphead_number, shiphead_order_id, shiphead_order_type,
	shiphead_shipped,
	shiphead_sfstatus, shiphead_shipvia, shiphead_shipchrg_id,
	shiphead_freight, shiphead_freight_curr_id,
	shiphead_shipdate, shiphead_notes, shiphead_shipform_id )
      SELECT _shipheadid, _shipnumber, coitem_cohead_id, pordertype,
	     FALSE,
	     'N', cohead_shipvia,
	     CASE WHEN (cohead_shipchrg_id <= 0) THEN NULL
	          ELSE cohead_shipchrg_id
	     END,
	     cohead_freight, cohead_curr_id,
	     _timestamp::DATE, cohead_shipcomments,
	     CASE WHEN cohead_shipform_id = -1 THEN NULL
	          ELSE cohead_shipform_id
	     END
      FROM cohead, coitem
      WHERE ((coitem_cohead_id=cohead_id)
         AND (coitem_id=pitemid) );

      UPDATE pack
      SET pack_shiphead_id = _shipheadid,
	  pack_printed = FALSE
      FROM coitem
      WHERE ((pack_head_id=coitem_cohead_id)
	AND  (pack_shiphead_id IS NULL)
	AND  (pack_head_type='SO')
	AND  (coitem_id=pitemid));

    ELSE
      UPDATE pack
      SET pack_printed = FALSE
      FROM coitem
      WHERE ((pack_head_id=coitem_cohead_id)
	AND  (pack_shiphead_id=_shipheadid)
	AND  (pack_head_type='SO')
	AND  (coitem_id=pitemid));
    END IF;

    -- Handle g/l transaction
    SELECT postInvTrans( itemsite_id, 'SH', (pQty * coitem_qty_invuomratio),
			   'S/R', porderType,
			   formatSoNumber(coitem_id), shiphead_number,
                           ('Issue ' || item_number || ' to Shipping for customer ' || cohead_billtoname),
			   getPrjAccntId(cohead_prj_id, costcat_shipasset_accnt_id), costcat_asset_accnt_id,
			   _itemlocSeries, _timestamp, NULL, pinvhistid ) INTO _invhistid
    FROM coitem, cohead, itemsite, item, costcat, shiphead
    WHERE ( (coitem_cohead_id=cohead_id)
     AND (coitem_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (itemsite_costcat_id=costcat_id)
     AND (coitem_id=pitemid)
     AND (shiphead_id=_shipheadid) );

    SELECT (invhist_unitcost * invhist_invqty) INTO _value
    FROM invhist
    WHERE (invhist_id=_invhistid);

    _shipitemid := nextval('shipitem_shipitem_id_seq');
    INSERT INTO shipitem
    ( shipitem_id, shipitem_shiphead_id, shipitem_orderitem_id, shipitem_qty,
      shipitem_transdate, shipitem_trans_username, shipitem_invoiced,
      shipitem_value, shipitem_invhist_id )
    VALUES
    ( _shipitemid, _shipheadid, pitemid, pQty,
      _timestamp, getEffectiveXtUser(), FALSE,
      _value, 
      CASE WHEN _invhistid = -1 THEN
        NULL
      ELSE 
        _invhistid
      END );

    -- Handle reservation
    IF (fetchmetricbool('EnableSOReservations')) THEN
      -- Remember what was reserved so we can re-reserve if this issue is returned
      INSERT INTO shipitemrsrv 
        (shipitemrsrv_shipitem_id, shipitemrsrv_qty)
      SELECT _shipitemid, least(pQty,coitem_qtyreserved)
      FROM coitem
      WHERE ((coitem_id=pitemid)
      AND (coitem_qtyreserved > 0));

      -- Update sales order
      UPDATE coitem
        SET coitem_qtyreserved = noNeg(coitem_qtyreserved - pQty)
      WHERE(coitem_id=pitemid);
    END IF;

    -- Calculate shipment freight
    SELECT calcShipFreight(_shipheadid) INTO _freight;
    UPDATE shiphead SET shiphead_freight=_freight
    WHERE (shiphead_id=_shipheadid);

  ELSEIF (pordertype = 'TO') THEN

    -- Check site security
    IF (fetchMetricBool('MultiWhs')) THEN
      SELECT warehous_id INTO _warehouseid
      FROM toitem, tohead, site()
      WHERE ( (toitem_id=pitemid)
        AND   (tohead_id=toitem_tohead_id)
        AND   (warehous_id=tohead_src_warehous_id) );
          
      IF (NOT FOUND) THEN
        RETURN 0;
      END IF;
    END IF;

    SELECT postInvTrans( itemsite_id, 'SH', pQty, 'S/R',
			 pordertype, formatToNumber(toitem_id), '', 'Issue to Shipping',
			 costcat_shipasset_accnt_id, costcat_asset_accnt_id,
			 _itemlocSeries, _timestamp) INTO _invhistid
    FROM tohead, toitem, itemsite, costcat
    WHERE ((tohead_id=toitem_tohead_id)
      AND  (itemsite_item_id=toitem_item_id)
      AND  (itemsite_warehous_id=tohead_src_warehous_id)
      AND  (itemsite_costcat_id=costcat_id)
      AND  (toitem_id=pitemid) );

    SELECT shiphead_id INTO _shipheadid
    FROM shiphead, toitem
    WHERE ((shiphead_order_id=toitem_tohead_id)
      AND  (NOT shiphead_shipped)
      AND  (toitem_id=pitemid)
      AND  (shiphead_order_type=pordertype));

    IF (NOT FOUND) THEN
      _shipheadid := NEXTVAL('shiphead_shiphead_id_seq');

      _shipnumber := fetchShipmentNumber();
      IF (_shipnumber < 0) THEN
	RETURN -10;
      END IF;

      INSERT INTO shiphead
      ( shiphead_id, shiphead_number, shiphead_order_id, shiphead_order_type,
	shiphead_shipped,
	shiphead_sfstatus, shiphead_shipvia, shiphead_shipchrg_id,
	shiphead_freight, shiphead_freight_curr_id,
	shiphead_shipdate, shiphead_notes, shiphead_shipform_id )
      SELECT _shipheadid, _shipnumber, tohead_id, pordertype,
	     FALSE,
	     'N', tohead_shipvia, tohead_shipchrg_id,
	     tohead_freight + SUM(toitem_freight), tohead_freight_curr_id,
	     _timestamp::DATE, tohead_shipcomments, tohead_shipform_id
      FROM tohead, toitem
      WHERE ((toitem_tohead_id=tohead_id)
         AND (tohead_id IN (SELECT toitem_tohead_id
			    FROM toitem
			    WHERE (toitem_id=pitemid))) )
      GROUP BY tohead_id, tohead_shipvia, tohead_shipchrg_id, tohead_freight,
	       tohead_freight_curr_id, tohead_shipcomments, tohead_shipform_id;
    END IF;

    INSERT INTO shipitem
    ( shipitem_shiphead_id, shipitem_orderitem_id, shipitem_qty,
      shipitem_transdate, shipitem_trans_username, shipitem_value,
      shipitem_invhist_id )
    SELECT
      _shipheadid, pitemid, pQty,
      _timestamp, getEffectiveXtUser(), invhist_invqty * invhist_unitcost,
      _invhistid
    FROM toitem, item, invhist
    WHERE ((toitem_id=pitemid)
    AND (item_id=toitem_item_id)
    AND (invhist_id=_invhistid));

  ELSE
    RETURN -11;
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.issuewomaterial(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  _itemlocSeries INTEGER;

BEGIN

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  RETURN issueWoMaterial(pWomatlid, pQty, _itemlocSeries);

END;

Function: public.issuewomaterial(integer, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pMarkPush ALIAS FOR $3;
  _itemlocSeries INTEGER;

BEGIN
  RETURN issueWoMaterial(pWomatlid, pQty, pMarkPush, now());
END;

Function: public.issuewomaterial(integer, numeric, boolean, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pMarkPush ALIAS FOR $3;
  pGlDistTS ALIAS FOR $4;
  _itemlocSeries INTEGER;

BEGIN

  SELECT issueWoMaterial(pWomatlid, pQty, 0, pGlDistTS) INTO _itemlocSeries;
  IF (_itemlocSeries < 0) THEN
    RETURN _itemlocSeries;
  END IF;

  IF (pMarkPush) THEN
    UPDATE womatl
    SET womatl_issuemethod='S'
    WHERE ((womatl_issuemethod='M')
     AND (womatl_id=pWomatlid));
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.issuewomaterial(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  _p RECORD;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;

BEGIN
  RETURN issueWoMaterial(pWomatlid, pQty, pItemlocSeries, now());
END;

Function: public.issuewomaterial(integer, numeric, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  pMarkPush ALIAS FOR $4;
  _itemlocSeries INTEGER;

BEGIN
  RETURN issueWoMaterial(pWomatlid, pQty, pItemlocSeries,now());
END;

Function: public.issuewomaterial(integer, numeric, integer, boolean, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  pMarkPush ALIAS FOR $4;
  pGlDistTS ALIAS FOR $5;
  _itemlocSeries INTEGER;

BEGIN

  SELECT issueWoMaterial(pWomatlid, pQty, pItemlocSeries, pGlDistTS) INTO _itemlocSeries;

  IF (pMarkPush) THEN
    UPDATE womatl
    SET womatl_issuemethod='S'
    WHERE ((womatl_issuemethod='M')
     AND (womatl_id=pWomatlid));
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.issuewomaterial(integer, numeric, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN issueWoMaterial($1, $2, $3, $4, NULL);
END;

Function: public.issuewomaterial(integer, numeric, integer, timestamp with time zone, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  pGlDistTS ALIAS FOR $4;
  pInvhistid ALIAS FOR $5;
  _p RECORD;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;

BEGIN

  SELECT item_id,
         itemsite_id AS c_itemsite_id,
         wo_itemsite_id AS p_itemsite_id,
         itemsite_loccntrl, itemsite_controlmethod,
         womatl_wo_id, womatl_qtyreq, itemsite_item_id, womatl_uom_id, wo_prj_id,
         roundQty(item_fractional, itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, pQty)) AS qty,
         formatWoNumber(wo_id) AS woNumber,
         CASE WHEN(itemsite_costmethod='J' AND item_type='P' AND poitem_id IS NOT NULL) THEN poitem_unitprice
              WHEN(itemsite_costmethod IN ('A','J')) THEN avgcost(itemsite_id)
              WHEN(itemsite_costmethod='S') THEN stdcost(itemsite_item_id)
              ELSE 0.0
         END AS cost,
         womatl_issuemethod AS issueMethod INTO _p
  FROM womatl JOIN wo ON (wo_id=womatl_wo_id)
              JOIN itemsite ON (itemsite_id=womatl_itemsite_id)
              JOIN item ON (item_id=itemsite_item_id)
              LEFT OUTER JOIN poitem ON (poitem_order_id=womatl_id AND poitem_order_type='W')
  WHERE (womatl_id=pWomatlid);

  IF (pQty < 0) THEN
    RETURN pItemlocSeries;
  END IF;

  IF (pItemlocSeries <> 0) THEN
    _itemlocSeries := pItemlocSeries;
  ELSE
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  END IF;
  SELECT postInvTrans( ci.itemsite_id, 'IM', _p.qty,
                      'W/O', 'WO', _p.woNumber, '',
                      ('Material ' || item_number || ' Issue to Work Order'),
                      getPrjAccntId(_p.wo_prj_id, pc.costcat_wip_accnt_id),
                      cc.costcat_asset_accnt_id, _itemlocSeries, pGlDistTS,
                      NULL, pInvhistid ) INTO _invhistid
  FROM itemsite AS ci, itemsite AS pi,
       costcat AS cc, costcat AS pc,
       item
  WHERE ( (ci.itemsite_costcat_id=cc.costcat_id)
   AND (pi.itemsite_costcat_id=pc.costcat_id)
   AND (ci.itemsite_id=_p.c_itemsite_id)
   AND (pi.itemsite_id=_p.p_itemsite_id)
   AND (ci.itemsite_item_id=item_id) );

--  Create linkage to the transaction created
  IF (_invhistid != -1) THEN
    INSERT INTO womatlpost (womatlpost_womatl_id,womatlpost_invhist_id)
                VALUES (pWomatlid,_invhistid);
  END IF;

--  Increase the parent W/O's WIP value by the value of the issued components
  UPDATE wo
  SET wo_wipvalue = (wo_wipvalue + (_p.cost * _p.qty)),
      wo_postedvalue = (wo_postedvalue + (_p.cost * _p.qty))
  WHERE (wo_id=_p.womatl_wo_id);

  UPDATE womatl
  SET womatl_qtyiss = (womatl_qtyiss + itemuomtouom(_p.itemsite_item_id, NULL, _p.womatl_uom_id, _p.qty)),
      womatl_lastissue = pGlDistTS::DATE
  WHERE (womatl_id=pWomatlid);

  UPDATE wo
  SET wo_status='I'
  WHERE ( (wo_status <> 'I')
   AND (wo_id=_p.womatl_wo_id) );

  RETURN _itemlocSeries;

END;

Function: public.issuewomaterialbatch(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  _itemlocSeries INTEGER;
  _r RECORD;
  _woNumber TEXT;

BEGIN

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;

  FOR _r IN SELECT womatl_id, 
              CASE WHEN (womatl_qtyreq >= 0) THEN
                roundQty(itemuomfractionalbyuom(item_id, womatl_uom_id), noNeg(womatl_qtyreq - womatl_qtyiss))
              ELSE
                roundQty(itemuomfractionalbyuom(item_id, womatl_uom_id), noNeg(womatl_qtyiss * -1)) 
              END AS qty
            FROM womatl, itemsite, item
            WHERE ( (womatl_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (womatl_issuemethod IN ('S', 'M'))
             AND (womatl_wo_id=pWoid) ) LOOP

    IF (_r.qty > 0) THEN
      SELECT issueWoMaterial(_r.womatl_id, _r.qty, _itemlocSeries, TRUE) INTO _itemlocSeries;
    END IF;

  END LOOP;

  RETURN _itemlocSeries;

END;

Function: public.itemaltcapinvrat(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
  RETURN itemUOMRatioByType(pItemid, 'AltCapacity');
END;

Function: public.itemaltcapuom(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
  RETURN itemUOMByType(pItemid, 'AltCapacity');
END;

Function: public.itemcapinvrat(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
  RETURN itemUOMRatioByType(pItemid, 'Capacity');
END;

Function: public.itemcapuom(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
  RETURN itemUOMByType(pItemid, 'Capacity');
END;

Function: public.itemcharprice(integer, integer, text, integer, integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharid ALIAS FOR $2;
  pCharValue ALIAS FOR $3;
  pCustid ALIAS FOR $4;
  pShiptoid ALIAS FOR $5;
  pQty ALIAS FOR $6;

BEGIN
  RETURN itemCharPrice(pItemid, pCharid, pCharValue, pCustid, pShiptoid, pQty, baseCurrId(), CURRENT_DATE);
END;

Function: public.itemcharprice(integer, integer, text, integer, integer, numeric, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharid ALIAS FOR $2;
  pCharValue ALIAS FOR $3;
  pCustid ALIAS FOR $4;
  pShiptoid ALIAS FOR $5;
  pQty ALIAS FOR $6;
  pCurrid ALIAS FOR $7;

BEGIN
  RETURN itemCharPrice(pItemid, pCharid, pCharValue, pCustid, pShiptoid, pQty, pCurrid, CURRENT_DATE);
END;

Function: public.itemcharprice(integer, integer, text, integer, integer, numeric, integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharid ALIAS FOR $2;
  pCharValue ALIAS FOR $3;
  pCustid ALIAS FOR $4;
  pShiptoid ALIAS FOR $5;
  pQty ALIAS FOR $6;
  pCurrid ALIAS FOR $7;
  pEffective ALIAS FOR $8;

BEGIN
  RETURN itemCharPrice(pItemid, pCharid, pCharValue, pCustid, pShiptoid, pQty, pCurrid, CURRENT_DATE, CURRENT_DATE);
END;

Function: public.itemcharprice(integer, integer, text, integer, integer, numeric, integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharid ALIAS FOR $2;
  pCharValue ALIAS FOR $3;
  pCustid ALIAS FOR $4;
  pShiptoid ALIAS FOR $5;
  pQty ALIAS FOR $6;
  pCurrid ALIAS FOR $7;
  pEffective ALIAS FOR $8;
  pAsOf ALIAS FOR $9;
  _price NUMERIC;
  _sales NUMERIC;
  _item RECORD;
  _iteminvpricerat NUMERIC;

BEGIN
-- If the charass_value passed in is NULL, we can skip this function
  IF (pCharValue IS NULL) THEN 
    RETURN 0;
  END IF;

-- Return the itemCharPrice in the currency passed in as pCurrid

-- Get a value here so we do not have to call the function several times
  SELECT iteminvpricerat(pItemid)
    INTO _iteminvpricerat;

-- First get a sales price if any so we when we find other prices
-- we can determine if we want that price or this price.
--  Check for a Sale Price
  SELECT currToCurr(ipshead_curr_id, pCurrid,
                      ipsprice_price - (ipsprice_price * cust_discntprcnt),
                      pEffective) INTO _sales
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, sale, custinfo
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (sale_ipshead_id=ipshead_id)
   AND (pAsOf BETWEEN sale_startdate AND sale_enddate)
   AND (ipsprice_qtybreak <= pQty)
   AND (cust_id=pCustid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

--  Check for a Customer Shipto Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _price
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE ((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, ipsass
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (ipsass_ipshead_id=ipshead_id)
   AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
   AND (ipsprice_qtybreak <= pQty)
   AND (ipsass_shipto_id != -1)
   AND (ipsass_shipto_id=pShiptoid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

  IF (_price IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _price)) THEN
      RETURN _sales;
    END IF;
    RETURN _price;
  END IF;

--  Check for a Customer Shipto Pattern Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _price
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE ((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, ipsass, shiptoinfo
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (ipsass_ipshead_id=ipshead_id)
   AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
   AND (ipsprice_qtybreak <= pQty)
   AND (COALESCE(length(ipsass_shipto_pattern), 0) > 0)
   AND (shipto_num ~ ipsass_shipto_pattern)
   AND (ipsass_cust_id=pCustid)
   AND (shipto_id=pShiptoid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

  IF (_price IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _price)) THEN
      RETURN _sales;
    END IF;
    RETURN _price;
  END IF;

--  Check for a Customer Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _price
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE ((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, ipsass
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (ipsass_ipshead_id=ipshead_id)
   AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
   AND (ipsprice_qtybreak <= pQty)
   AND (COALESCE(length(ipsass_shipto_pattern), 0) = 0)
   AND (ipsass_cust_id=pCustid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

  IF (_price IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _price)) THEN
      RETURN _sales;
    END IF;
    RETURN _price;
  END IF;

--  Check for a Customer Type Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _price
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, ipsass, custinfo
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (ipsass_ipshead_id=ipshead_id)
   AND (ipsass_custtype_id=cust_custtype_id)
   AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
   AND (ipsprice_qtybreak <= pQty)
   AND (cust_id=pCustid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

  IF (_price IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _price)) THEN
      RETURN _sales;
    END IF;
    RETURN _price;
  END IF;

--  Check for a Customer Type Pattern Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _price
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak) AS ipsprice_qtybreak,
         (ipsitemchar_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat AS ipsprice_price
    FROM ipsiteminfo,ipsitemchar
   WHERE ((ipsitem_item_id=pItemid)
    AND (ipsitemchar_char_id=pCharid)
    AND (ipsitemchar_value=pCharValue)
    AND (ipsitemchar_ipsitem_id=ipsitem_id))
       ) AS
        ipsprice, ipshead, ipsass, custtype, custinfo
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
   AND (ipsass_ipshead_id=ipshead_id)
   AND (coalesce(length(ipsass_custtype_pattern), 0) > 0)
   AND (custtype_code ~ ipsass_custtype_pattern)
   AND (cust_custtype_id=custtype_id)
   AND (pAsOf BETWEEN ipshead_effective AND (ipshead_expires - 1))
   AND (ipsprice_qtybreak <= pQty)
   AND (cust_id=pCustid) )
  ORDER BY ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

  IF (_price IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _price)) THEN
      RETURN _sales;
    END IF;
    RETURN _price;
  END IF;

-- If we have not found another price yet and we have a
-- sales price we will use that.
  IF (_sales IS NOT NULL) THEN
    RETURN _sales;
  END IF;

--  Check for a list price
  SELECT MIN(currToLocal(pCurrid,
                       charass_price - (charass_price * COALESCE(cust_discntprcnt, 0)),
                       pEffective)) AS price,
         item_exclusive INTO _item
  FROM charass,item LEFT OUTER JOIN custinfo ON (cust_id=pCustid)
  WHERE ((item_id=pItemid)
   AND (charass_char_id=pCharid)
   AND (charass_value=pCharValue)
   AND (charass_target_type='I')
   AND (charass_target_id=item_id))
  GROUP BY item_exclusive;
  IF (FOUND) THEN
    IF (NOT _item.item_exclusive) THEN
      IF (_item.price < 0) THEN
        RETURN 0;
      ELSE
        RETURN _item.price;
      END IF;
    ELSE
      RETURN 0;
    END IF;
  ELSE
    RETURN 0;
  END IF;

END;

Function: public.itemcharprice(integer, integer, text, integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharid ALIAS FOR $2;
  pCharValue ALIAS FOR $3;
  pCustid ALIAS FOR $4;
  pQty ALIAS FOR $5;

BEGIN
  RETURN itemCharPrice(pItemid, pCharid, pCharValue, pCustid, -1, pQty, baseCurrId(), CURRENT_DATE);
END;

Function: public.itemcharvalue(integer, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCharName ALIAS FOR $2;
  _value TEXT;

BEGIN

  SELECT charass_value INTO _value
  FROM charass, char
  WHERE ( (charass_char_id=char_id)
   AND (charass_target_type='I')
   AND (charass_target_id=pItemid)
   AND (char_name=pCharName) );
  IF (NOT FOUND) THEN
    _value = '';
  END IF;

  RETURN _value;

END;

Function: public.itemcost(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _cost NUMERIC;
BEGIN
  SELECT CASE WHEN (itemsite_costmethod='A' AND itemsite_qtyonhand != 0.0) THEN (itemsite_value / itemsite_qtyonhand)
              WHEN (itemsite_costmethod='A' AND itemsite_qtyonhand = 0.0) THEN 0.0
              WHEN (itemsite_costmethod='N') THEN 0.0
              ELSE stdCost(itemsite_item_id)
         END INTO _cost
    FROM itemsite
   WHERE(itemsite_id=pItemsiteid);
  RETURN _cost;
END;

Function: public.iteminventoryuominuse(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _uomid INTEGER;
  _result INTEGER;
BEGIN
  SELECT item_inv_uom_id INTO _uomid
    FROM item
   WHERE(item_id=pItemid);

  SELECT itemuomconv_id INTO _result
    FROM itemuomconv
   WHERE(itemuomconv_item_id=pItemid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;

  SELECT itemsite_id INTO _result
  FROM itemsite WHERE ( (itemsite_item_id=pItemid)
                  AND   ((itemsite_qtyonhand <> 0) OR (itemsite_nnqoh <> 0)) )
  LIMIT 1;
  IF (FOUND) THEN
    RETURN TRUE;
  END IF;

  RETURN FALSE;
END;

Function: public.iteminvpricerat(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _fromUomid INTEGER;
  _toUomid INTEGER;
  _ratio NUMERIC;
BEGIN

  IF(pItemid IS NULL) THEN
    RETURN 1.0;
  END IF;

  SELECT item_inv_uom_id, item_price_uom_id
    INTO _fromUomid, _toUomid
    FROM item
   WHERE(item_id=pItemid);

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'No item record found for item_id %', pItemid;
  END IF;

  IF(_fromUomid = _toUomid) THEN
    RETURN 1.0;
  END IF;

  -- Return the ration as inventory / price
  SELECT CASE WHEN(itemuomconv_from_uom_id=_fromUomid) THEN itemuomconv_from_value / itemuomconv_to_value
              ELSE itemuomconv_to_value / itemuomconv_from_value
         END
    INTO _ratio
    FROM itemuomconv
   WHERE((((itemuomconv_from_uom_id=_fromUomid) AND (itemuomconv_to_uom_id=_toUomid))
       OR ((itemuomconv_from_uom_id=_toUomid) AND (itemuomconv_to_uom_id=_fromUomid)))
     AND (itemuomconv_item_id=pItemid));

  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'No itemuomconv record found for item_id % to item_price_uomid %', pItemid, _toUomid;
  END IF;
  
  RETURN _ratio;
END;

Function: public.itemipsprice(psiteid integer, pasof integer, peffective integer, pcurrid numeric, ppriceuom integer, pqtyuom integer, pqty integer, pshiptoid date, pcustid date, pitemid integer)

Returns: SET OF itemprice

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row  itemprice%ROWTYPE;
  _sale RECORD;
  _ips RECORD;
  _item RECORD;
  _cust RECORD;
  _shipto RECORD;
  _iteminvpricerat NUMERIC := 1.0;
  _listprice NUMERIC := 0.0;
  _qty NUMERIC;
  _asof DATE;

BEGIN
-- Return the itemPrice in the currency passed in as pCurrid
  _qty := itemuomtouom(pItemid, pQtyUOM, NULL, pQty);

-- If no as of passed, use current date
  _asof := COALESCE(pAsOf, CURRENT_DATE);

-- Get a value here so we do not have to call the function several times
  SELECT itemuomtouomratio(pItemid, pPriceUOM, NULL) AS ratio
    INTO _iteminvpricerat;

--  Cache Item, Customer and Shipto
  SELECT * INTO _item
  FROM item
  WHERE (item_id=pItemid);

  SELECT * INTO _cust
  FROM custinfo JOIN custtype ON (custtype_id=cust_custtype_id)
  WHERE (cust_id=pCustid);

  SELECT * INTO _shipto
  FROM shiptoinfo
  WHERE (shipto_id=pShiptoid);

-- First get a sales price if any so we when we find other prices
-- we can determine if we want that price or this price.
--  Check for a Sale Price
  SELECT INTO _sale
    currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) AS rightprice, ipsitem_type AS righttype
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id, ipsitem_type,
         CASE WHEN ipsitem_type = 'N' THEN (ipsitem_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat
              WHEN ipsitem_type = 'D' THEN noNeg(_item.item_listprice - (_item.item_listprice * ipsitem_discntprcnt) - ipsitem_fixedamtdiscount)
              WHEN ipsitem_type = 'M' THEN (_item.item_listcost + (_item.item_listcost * ipsitem_discntprcnt) + ipsitem_fixedamtdiscount)
              ELSE 0.00
         END AS ipsprice_price,
         CASE WHEN (ipsitem_item_id=_item.item_id) THEN itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak)
              ELSE ipsitem_qtybreak
         END AS ipsprice_qtybreak,
         (ipsitem_price_uom_id=COALESCE(pPriceUOM,-1)) AS uommatched
    FROM ipsiteminfo
   WHERE(ipsitem_item_id=_item.item_id) OR (ipsitem_prodcat_id=_item.item_prodcat_id) ) AS
        ipsprice, ipshead, sale
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
    AND   (sale_ipshead_id=ipsprice_ipshead_id)
    AND   (_asof BETWEEN sale_startdate AND sale_enddate)
    AND   (ipsprice_qtybreak <= _qty) )
  ORDER BY uommatched DESC, ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

-- Find the best Price Schedule Price
 
  SELECT INTO _ips
    currToCurr(ipshead_curr_id, pCurrid, protoprice, pEffective) AS rightprice, ipsitem_type AS righttype
  
  FROM (
    SELECT *,
           CASE WHEN (COALESCE(ipsass_shipto_id, -1) > 0) THEN 1
             WHEN (COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0) THEN 2
             WHEN (COALESCE(ipsass_cust_id, -1) > 0) THEN 3
             WHEN (COALESCE(ipsass_custtype_id, -1) > 0) THEN 4
             WHEN (COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0) THEN 5
             ELSE 99
           END AS assignseq,
           CASE WHEN ipsitem_type = 'N' THEN (ipsitem_price * itemuomtouomratio(_item.item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat
                WHEN ipsitem_type = 'D' THEN noNeg(_item.item_listprice - (_item.item_listprice * ipsitem_discntprcnt) - ipsitem_fixedamtdiscount)
                WHEN ipsitem_type = 'M' THEN (_item.item_listcost + (_item.item_listcost * ipsitem_discntprcnt) + ipsitem_fixedamtdiscount)
                ELSE 0.00
           END AS protoprice,
           CASE WHEN (ipsitem_item_id=_item.item_id) THEN itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak)
                ELSE ipsitem_qtybreak
           END AS protoqtybreak,
           (COALESCE(ipsitem_price_uom_id, -1)=COALESCE(pPriceUOM, -1)) AS uommatched
    FROM ipsass JOIN ipshead ON (ipshead_id=ipsass_ipshead_id)
                JOIN ipsiteminfo ON (ipsitem_ipshead_id=ipshead_id)
    WHERE ((ipsitem_item_id=_item.item_id) OR (ipsitem_prodcat_id=_item.item_prodcat_id))
      AND (_asof BETWEEN ipshead_effective AND ipshead_expires)
      AND ((ipsitem_warehous_id=pSiteid) OR (pSiteid IS NULL))
      AND ( (ipsass_shipto_id=_shipto.shipto_id)
       OR   ((COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0) AND (_shipto.shipto_num ~ ipsass_shipto_pattern))
       OR   (ipsass_cust_id=_cust.cust_id)
       OR   (ipsass_custtype_id=_cust.cust_custtype_id)
       OR   ((COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0) AND (_cust.custtype_code ~ ipsass_custtype_pattern))
          )
  ) AS proto
  WHERE (protoqtybreak <= pQty)
  ORDER BY assignseq, protoqtybreak DESC, rightprice
  LIMIT 1;
 
  IF (_ips.rightprice IS NOT NULL) THEN
    IF ((_sale.rightprice IS NOT NULL) AND (_sale.rightprice < _ips.rightprice)) THEN
      RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, sale price= %', pItemid, pCustid, pShiptoid, _sale.rightprice;
      _row.itemprice_price := _sale.rightprice;
      _row.itemprice_type := _sale.righttype;
      RETURN NEXT _row;
    END IF;
    RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, schedule price= %', pItemid, pCustid, pShiptoid, _ips.rightprice;
    _row.itemprice_price := _ips.rightprice;
    _row.itemprice_type := _ips.righttype;
    RETURN NEXT _row;
  END IF;

--  If item is exclusive then list list price does not apply
  IF (_item.item_exclusive) THEN
    RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, item exclusive, price=-9999', pItemid, pCustid, pShiptoid;
    _row.itemprice_price := -9999.0;
    _row.itemprice_type := '';
    RETURN NEXT _row;
  END IF;

--  Check for a list price
  _listprice := noNeg(currToLocal(pCurrid, _item.item_listprice - (_item.item_listprice * COALESCE(_cust.cust_discntprcnt, 0.0)), pEffective)
                      * itemuomtouomratio(pItemid, pPriceUOM, _item.item_price_uom_id));

  RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, list price= %', pItemid, pCustid, pShiptoid, _listprice;

  _row.itemprice_price := _listprice;
  _row.itemprice_type := 'P';
  RETURN NEXT _row;

  RETURN;

END;

Function: public.itemlocdistqty(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  pParentid ALIAS FOR $2;
  _qty NUMERIC;
  _tempQty NUMERIC;

BEGIN

  SELECT COALESCE(SUM(itemlocdist_qty), 0) INTO _qty
  FROM itemlocdist
  WHERE ( (itemlocdist_source_type='L')
   AND (itemlocdist_source_id=pLocationid)
   AND (itemlocdist_itemlocdist_id=pParentid) );

  SELECT COALESCE(SUM(itemlocdist_qty), 0) INTO _tempQty
  FROM itemlocdist, itemloc
  WHERE ( (itemlocdist_source_type='I')
   AND (itemlocdist_source_id=itemloc_id)
   AND (itemloc_location_id=pLocationid)
   AND (itemlocdist_itemlocdist_id=pParentid) );

  _qty := (_qty + _tempQty);

  RETURN _qty;

END;

Function: public.itemlocdistqty(text, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTypes ALIAS FOR $1;
  pLocationid ALIAS FOR $2;
  pParentid ALIAS FOR $3;
  _qty NUMERIC := 0;
  _tempQty NUMERIC;

BEGIN

  IF (strpos(pTypes, 'L') > 0) THEN
    SELECT COALESCE(SUM(itemlocdist_qty), 0) INTO _tempQty
    FROM itemlocdist
    WHERE ( (itemlocdist_source_type='L')
     AND (itemlocdist_source_id=pLocationid)
     AND (itemlocdist_itemlocdist_id=pParentid) );

    _qty := (_qty + _tempQty);
  END IF;

  IF (strpos(pTypes, 'I') > 0) THEN
    SELECT COALESCE(SUM(itemlocdist_qty), 0) INTO _tempQty
    FROM itemlocdist, itemloc
    WHERE ( (itemlocdist_source_type='I')
     AND (itemlocdist_source_id=itemloc_id)
     AND (itemloc_location_id=pLocationid)
     AND (itemlocdist_itemlocdist_id=pParentid) );

    _qty := (_qty + _tempQty);
  END IF;

  RETURN _qty;

END;

Function: public.itemprice(pasof integer, peffective integer, pcurrid integer, ppriceuom numeric, pqtyuom integer, pqty integer, pshiptoid integer, pcustid date, pitemid date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  pShiptoid ALIAS FOR $3;
  pQty ALIAS FOR $4;
  pQtyUOM ALIAS FOR $5;
  pPriceUOM ALIAS FOR $6;
  pCurrid ALIAS FOR $7;
  pEffective ALIAS FOR $8;
  pAsOf ALIAS FOR $9;

BEGIN
  RETURN itemPrice(pItemid, pCustid, pShiptoid, pQty, pQtyUOM, pPriceUOM, pCurrid, pEffective, pAsOf, NULL);
END;

Function: public.itemprice(peffective integer, pcurrid integer, ppriceuom integer, pqtyuom numeric, pqty integer, pshiptoid integer, pcustid integer, pitemid date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  RETURN itemPrice(pItemid, pCustid, pShiptoid, pQty, pQtyUOM, pPriceUOM, pCurrid, pEffective, CURRENT_DATE);
END;

Function: public.itemprice(peffective integer, pcurrid integer, pqty integer, pshiptoid numeric, pcustid integer, pitemid date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _item RECORD;

BEGIN
  SELECT item_inv_uom_id, item_price_uom_id
    INTO _item
    FROM item
   WHERE(item_id=pItemid);
  IF (FOUND) THEN
    RETURN itemPrice(pItemid, pCustid, pShiptoid, pQty, _item.item_inv_uom_id, _item.item_price_uom_id, pCurrid, pEffective);
  END IF;
  RETURN -9999;
END;

Function: public.itemprice(psiteid integer, pasof integer, peffective integer, pcurrid numeric, ppriceuom integer, pqtyuom integer, pqty integer, pshiptoid date, pcustid date, pitemid integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _price NUMERIC;
  _sales NUMERIC;
  _r RECORD;
  _item RECORD;
  _cust RECORD;
  _shipto RECORD;
  _iteminvpricerat NUMERIC;
  _qty NUMERIC;
  _asof DATE;

BEGIN
-- Return the itemPrice in the currency passed in as pCurrid
  _qty := itemuomtouom(pItemid, pQtyUOM, NULL, pQty);

-- If no as of passed, use current date
  _asof := COALESCE(pAsOf, CURRENT_DATE);

-- Get a value here so we do not have to call the function several times
  SELECT itemuomtouomratio(pItemid, pPriceUOM, NULL) AS ratio
    INTO _iteminvpricerat;

--  Cache Item, Customer and Shipto
  SELECT * INTO _item
  FROM item
  WHERE (item_id=pItemid);

  SELECT * INTO _cust
  FROM custinfo JOIN custtype ON (custtype_id=cust_custtype_id)
  WHERE (cust_id=pCustid);

  SELECT * INTO _shipto
  FROM shiptoinfo
  WHERE (shipto_id=pShiptoid);

-- First get a sales price if any so we when we find other prices
-- we can determine if we want that price or this price.
--  Check for a Sale Price
  SELECT currToCurr(ipshead_curr_id, pCurrid, ipsprice_price, pEffective) INTO _sales
  FROM (
  SELECT ipsitem_ipshead_id AS ipsprice_ipshead_id,
         CASE WHEN ipsitem_type = 'N' THEN (ipsitem_price * itemuomtouomratio(ipsitem_item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat
              WHEN ipsitem_type = 'D' THEN noNeg(_item.item_listprice - (_item.item_listprice * ipsitem_discntprcnt) - ipsitem_fixedamtdiscount)
              WHEN ipsitem_type = 'M' THEN (_item.item_listcost + (_item.item_listcost * ipsitem_discntprcnt) + ipsitem_fixedamtdiscount)
              ELSE 0.00
         END AS ipsprice_price,
         CASE WHEN (ipsitem_item_id=_item.item_id) THEN itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak)
              ELSE ipsitem_qtybreak
         END AS ipsprice_qtybreak,
         (ipsitem_price_uom_id=COALESCE(pPriceUOM,-1)) AS uommatched
    FROM ipsiteminfo
   WHERE(ipsitem_item_id=_item.item_id) OR (ipsitem_prodcat_id=_item.item_prodcat_id) ) AS
        ipsprice, ipshead, sale
  WHERE ( (ipsprice_ipshead_id=ipshead_id)
    AND   (sale_ipshead_id=ipsprice_ipshead_id)
    AND   (_asof BETWEEN sale_startdate AND sale_enddate)
    AND   (ipsprice_qtybreak <= _qty) )
  ORDER BY uommatched DESC, ipsprice_qtybreak DESC, ipsprice_price ASC
  LIMIT 1;

-- Find the best Price Schedule Price
 
  SELECT INTO _r
    *, currToCurr(ipshead_curr_id, pCurrid, protoprice, pEffective) AS rightprice
  
  FROM (
    SELECT *,
           CASE WHEN (COALESCE(ipsass_shipto_id, -1) > 0) THEN 1
             WHEN (COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0) THEN 2
             WHEN (COALESCE(ipsass_cust_id, -1) > 0) THEN 3
             WHEN (COALESCE(ipsass_custtype_id, -1) > 0) THEN 4
             WHEN (COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0) THEN 5
             ELSE 99
           END AS assignseq,
           CASE WHEN ipsitem_type = 'N' THEN (ipsitem_price * itemuomtouomratio(_item.item_id, NULL, ipsitem_price_uom_id)) * _iteminvpricerat
                WHEN ipsitem_type = 'D' THEN noNeg(_item.item_listprice - (_item.item_listprice * ipsitem_discntprcnt) - ipsitem_fixedamtdiscount)
                WHEN ipsitem_type = 'M' THEN (_item.item_listcost + (_item.item_listcost * ipsitem_discntprcnt) + ipsitem_fixedamtdiscount)
                ELSE 0.00
           END AS protoprice,
           CASE WHEN (ipsitem_item_id=_item.item_id) THEN itemuomtouom(ipsitem_item_id, ipsitem_qty_uom_id, NULL, ipsitem_qtybreak)
                ELSE ipsitem_qtybreak
           END AS protoqtybreak,
           (COALESCE(ipsitem_price_uom_id, -1)=COALESCE(pPriceUOM, -1)) AS uommatched
    FROM ipsass JOIN ipshead ON (ipshead_id=ipsass_ipshead_id)
                JOIN ipsiteminfo ON (ipsitem_ipshead_id=ipshead_id)
    WHERE ((ipsitem_item_id=_item.item_id) OR (ipsitem_prodcat_id=_item.item_prodcat_id))
      AND (_asof BETWEEN ipshead_effective AND ipshead_expires)
      AND ((ipsitem_warehous_id=pSiteid) OR (pSiteid IS NULL))
      AND ( (ipsass_shipto_id=_shipto.shipto_id)
       OR   ((COALESCE(LENGTH(ipsass_shipto_pattern), 0) > 0) AND (_shipto.shipto_num ~ ipsass_shipto_pattern))
       OR   (ipsass_cust_id=_cust.cust_id)
       OR   (ipsass_custtype_id=_cust.cust_custtype_id)
       OR   ((COALESCE(LENGTH(ipsass_custtype_pattern), 0) > 0) AND (_cust.custtype_code ~ ipsass_custtype_pattern))
          )
  ) AS proto
  WHERE (protoqtybreak <= pQty)
  ORDER BY assignseq, protoqtybreak DESC, rightprice
  LIMIT 1;
 
  IF (_r.rightprice IS NOT NULL) THEN
    IF ((_sales IS NOT NULL) AND (_sales < _r.rightprice)) THEN
      RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, sale price= %', pItemid, pCustid, pShiptoid, _sales;
      RETURN _sales;
    END IF;
    RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, schedule price= %', pItemid, pCustid, pShiptoid, _r.rightprice;
    RETURN _r.rightprice;
  END IF;

--  If item is exclusive then list list price does not apply
  IF (_item.item_exclusive) THEN
    RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, item exclusive, price=-9999', pItemid, pCustid, pShiptoid;
    RETURN -9999.0;
  END IF;

--  Check for a list price
  _price := noNeg(currToLocal(pCurrid, _item.item_listprice - (_item.item_listprice * COALESCE(_cust.cust_discntprcnt, 0.0)), pEffective)
                  * itemuomtouomratio(pItemid, pPriceUOM, _item.item_price_uom_id));

  RAISE DEBUG 'itemprice, item=%, cust=%, shipto=%, list price= %', pItemid, pCustid, pShiptoid, _price;

  RETURN _price;

END;

Function: public.itemsellinguom(integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
  RETURN itemUOMByType(pItemid, 'Selling');
END;

Function: public.itemsrcprice(peffective integer, pcurrid integer, pqty boolean, pdropship numeric, psiteid integer, pitemsrcid date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _price NUMERIC := 0.0;
  _r RECORD;
  _effective DATE;

BEGIN
-- If no pEffective passed, use current date
  _effective := COALESCE(pEffective, CURRENT_DATE);

--  Cache Itemsrc and Item
  SELECT *
  INTO _r
  FROM itemsrc JOIN item ON (item_id=itemsrc_item_id)
  WHERE (itemsrc_id=pItemsrcid);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'itemsrc % not found.', pItemsrcid;
  END IF;

--  Determine price
  SELECT currToCurr(itemsrcp_curr_id, pCurrid, price, _effective) INTO _price
  FROM (
    SELECT *,
           CASE itemsrcp_type WHEN ('N') THEN itemsrcp_price
                              WHEN ('D') THEN (_r.item_listcost - (_r.item_listcost * itemsrcp_discntprcnt) - itemsrcp_fixedamtdiscount)
                              ELSE 0.0
           END AS price
    FROM itemsrcp
    WHERE ( (itemsrcp_itemsrc_id=_r.itemsrc_id)
      AND   ((itemsrcp_warehous_id=pSiteid) OR (itemsrcp_warehous_id=-1))
      AND   ((itemsrcp_dropship=pDropship) OR (NOT itemsrcp_dropship))
      AND   (itemsrcp_qtybreak <= pQty) )
    ORDER BY itemsrcp_qtybreak DESC
    LIMIT 1
       ) AS data
  ;

  RETURN _price;

END;

Function: public.itemsrcprice(peffective integer, pcurrid numeric, pqty integer, pitemsrcid date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _price NUMERIC := 0.0;

BEGIN

  SELECT itemsrcPrice(pItemsrcid, -1, FALSE, pQty, pCurrid, pEffective) INTO _price;

  RETURN _price;

END;

Function: public.itemuombytype(integer, text)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomtype ALIAS FOR $2;
  _uom TEXT;
BEGIN
  SELECT uom_name INTO _uom FROM (
  SELECT uom_name
    FROM item
    JOIN itemuomconv ON (itemuomconv_item_id=item_id)
    JOIN itemuom ON (itemuom_itemuomconv_id=itemuomconv_id)
    JOIN uomtype ON (itemuom_uomtype_id=uomtype_id)
    JOIN uom ON (itemuomconv_to_uom_id=uom_id)
   WHERE((item_id=pItemid)
     AND (uomtype_name=pUomtype)
     AND (item_inv_uom_id != itemuomconv_to_uom_id))
  UNION
  SELECT uom_name
    FROM item
    JOIN itemuomconv ON (itemuomconv_item_id=item_id)
    JOIN itemuom ON (itemuom_itemuomconv_id=itemuomconv_id)
    JOIN uomtype ON (itemuom_uomtype_id=uomtype_id)
    JOIN uom ON (itemuomconv_from_uom_id=uom_id)
   WHERE((item_id=pItemid)
     AND (uomtype_name=pUomtype)
     AND (item_inv_uom_id != itemuomconv_from_uom_id))) data
   LIMIT 1;

  IF (NOT FOUND) THEN
    SELECT uom_name
      INTO _uom
      FROM item
      JOIN uom ON (item_inv_uom_id=uom_id)
     WHERE(item_id=pItemid);
  END IF;

  RETURN _uom;
END;

Function: public.itemuomfractionalbytype(integer, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomtype ALIAS FOR $2;
  _frac BOOLEAN;
BEGIN
  SELECT itemuomconv_fractional
    INTO _frac
    FROM item
    JOIN itemuomconv ON (itemuomconv_item_id=item_id)
    JOIN itemuom ON (itemuom_itemuomconv_id=itemuomconv_id)
    JOIN uomtype ON (itemuom_uomtype_id=uomtype_id)
   WHERE((item_id=pItemid)
     AND (uomtype_name=pUomtype))
   LIMIT 1;

  IF (NOT FOUND) THEN
    SELECT item_fractional
      INTO _frac
      FROM item
      JOIN uom ON (item_inv_uom_id=uom_id)
     WHERE(item_id=pItemid);
  END IF;

  RETURN _frac;
END;

Function: public.itemuomfractionalbyuom(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomid ALIAS FOR $2;
  _frac BOOLEAN;
BEGIN
  SELECT itemuomconv_fractional
    INTO _frac
    FROM item
    JOIN itemuomconv ON (itemuomconv_item_id=item_id)
   WHERE((item_id=pItemid)
     AND ((itemuomconv_from_uom_id=item_inv_uom_id AND itemuomconv_to_uom_id=pUomid)
       OR (itemuomconv_to_uom_id=item_inv_uom_id AND itemuomconv_from_uom_id=pUomid)))
   LIMIT 1;

  IF (NOT FOUND) THEN
    SELECT item_fractional
      INTO _frac
      FROM item
      JOIN uom ON (item_inv_uom_id=uom_id)
     WHERE(item_id=pItemid);
  END IF;

  RETURN _frac;
END;

Function: public.itemuomratiobytype(integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomtype ALIAS FOR $2;
  _ratio NUMERIC;
BEGIN
  -- Return the ration as alternate / inventory uom
  SELECT CASE WHEN(itemuomconv_from_uom_id=item_inv_uom_id) THEN itemuomconv_to_value / itemuomconv_from_value
              ELSE itemuomconv_from_value / itemuomconv_to_value
         END
    INTO _ratio
    FROM item
    JOIN itemuomconv ON (itemuomconv_item_id=item_id)
    JOIN itemuom ON (itemuom_itemuomconv_id=itemuomconv_id)
    JOIN uomtype ON (itemuom_uomtype_id=uomtype_id)
   WHERE((item_id=pItemid)
     AND (uomtype_name=pUomtype))
   LIMIT 1;

  IF (NOT FOUND) THEN
    _ratio := 1.0;
  END IF;

  RETURN _ratio;
END;

Function: public.itemuomtouom(integer, integer, integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomidFrom ALIAS FOR $2;
  pUomidTo ALIAS FOR $3;
  pQtyFrom ALIAS FOR $4;

  _uomidFrom INTEGER;
  _uomidTo   INTEGER;
  _valueFrom NUMERIC;
  _valueTo   NUMERIC;
  _item      RECORD;
  _conv      RECORD;
  _frac      BOOLEAN;
BEGIN

  SELECT item_inv_uom_id, item_fractional
    INTO _item
    FROM item
   WHERE(item_id=pItemid);
  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'No item record was found for item id %', pItemid;
  END IF;

  _uomidFrom := COALESCE(pUomidFrom, _item.item_inv_uom_id);
  _uomidTo   := COALESCE(pUomidTo,   _item.item_inv_uom_id);

  -- Should we round the qty here or not?
  IF(_uomidFrom = _uomidTo) THEN
    -- Both from/to are the same. If it is the item inv uom
    -- then use the item fractional value otherwise assume
    -- it is fractional for now so the user gets the same value back.
    IF(_uomidFrom = _item.item_inv_uom_id) THEN
      _frac := _item.item_fractional;
    ELSE
      _frac := true;
    END IF;
    RETURN roundQty(_frac, pQtyFrom);
  END IF;

  IF(_uomidFrom != _item.item_inv_uom_id AND _uomidTo != _item.item_inv_uom_id) THEN
    RAISE EXCEPTION 'Converting from/to a UOM where one is not the inventory UOM is currently not supported';
  END IF;

  SELECT itemuomconv_from_uom_id, itemuomconv_from_value,
         itemuomconv_to_uom_id, itemuomconv_to_value,
         itemuomconv_fractional
    INTO _conv
    FROM itemuomconv
   WHERE(((itemuomconv_from_uom_id=_uomidFrom AND itemuomconv_to_uom_id=_uomidTo)
       OR (itemuomconv_from_uom_id=_uomidTo AND itemuomconv_to_uom_id=_uomidFrom))
     AND (itemuomconv_item_id=pItemid));
  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'A conversion for item_id % from uom_id % to uom_id % was not found.', pItemid, _uomidFrom, _uomidTo;
  END IF;

  IF(_conv.itemuomconv_from_uom_id=_uomidFrom) THEN
    _valueFrom := _conv.itemuomconv_from_value;
    _valueTo := _conv.itemuomconv_to_value;
  ELSE
    _valueFrom := _conv.itemuomconv_to_value;
    _valueTo := _conv.itemuomconv_from_value;
  END IF;

  -- If we are converting to the item inv uom use the item fractional value
  -- otherwise use the conversion fractional value.
  if(_uomidTo = _item.item_inv_uom_id) THEN
    _frac := _item.item_fractional;
  ELSE
    _frac := _conv.itemuomconv_fractional;
  END IF;

  RETURN roundQty(_frac, ((_valueTo/_valueFrom) * pQtyFrom));
END;

Function: public.itemuomtouomratio(integer, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUomidFrom ALIAS FOR $2;
  pUomidTo ALIAS FOR $3;

  _uomidFrom INTEGER;
  _uomidTo   INTEGER;
  _valueFrom NUMERIC;
  _valueTo   NUMERIC;
  _item      RECORD;
  _conv      RECORD;
BEGIN

  SELECT item_inv_uom_id
    INTO _item
    FROM item
   WHERE(item_id=pItemid);
  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'No item record was found for item id %', pItemid;
  END IF;

  _uomidFrom := COALESCE(pUomidFrom, _item.item_inv_uom_id);
  _uomidTo   := COALESCE(pUomidTo,   _item.item_inv_uom_id);

  IF(_uomidFrom = _uomidTo) THEN
    RETURN 1.0;
  END IF;

  IF(_uomidFrom != _item.item_inv_uom_id AND _uomidTo != _item.item_inv_uom_id) THEN
    RAISE EXCEPTION 'Converting from/to a UOM where one is not the inventory UOM is currently not supported';
  END IF;

  SELECT itemuomconv_from_uom_id, itemuomconv_from_value,
         itemuomconv_to_uom_id, itemuomconv_to_value
    INTO _conv
    FROM itemuomconv
   WHERE(((itemuomconv_from_uom_id=_uomidFrom AND itemuomconv_to_uom_id=_uomidTo)
       OR (itemuomconv_from_uom_id=_uomidTo AND itemuomconv_to_uom_id=_uomidFrom))
     AND (itemuomconv_item_id=pItemid));
  IF(NOT FOUND) THEN
    RAISE EXCEPTION 'A conversion for item_id % from uom_id % to uom_id % was not found.', pItemid, _uomidFrom, _uomidTo;
  END IF;

  IF(_conv.itemuomconv_from_uom_id=_uomidFrom) THEN
    _valueFrom := _conv.itemuomconv_from_value;
    _valueTo := _conv.itemuomconv_to_value;
  ELSE
    _valueFrom := _conv.itemuomconv_to_value;
    _valueTo := _conv.itemuomconv_from_value;
  END IF;

  RETURN (_valueTo/_valueFrom);
END;

Function: public.last(anyelement)

Returns: anyelement

Language: INTERNAL

aggregate_dummy

Function: public.last_agg(anyelement, anyelement)

Returns: anyelement

Language: SQL

  SELECT $2;

Function: public.login()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE 
  _p RECORD;

BEGIN

  PERFORM pg_try_advisory_lock(datid::integer, procpid)
     FROM pg_stat_activity
    WHERE(procpid = pg_backend_pid());

  -- This is new to version 9.0 and higher and will error on older versions
  IF (select CAST(split_part(split_part(version(), ' ', 2),'.',1) AS integer) >= 9) THEN
    SET bytea_output TO escape;
  END IF;

  -- this is temporary until either qt fixes the postgres driver or we find &
  -- fix all of the places in our app that can write strings with backslashes
  SET standard_conforming_strings TO false;

  SELECT usr_id, userCanLogin(usr_username) AS usr_active INTO _p
  FROM usr
  WHERE (usr_username=getEffectiveXtUser());

  IF (NOT FOUND) THEN
    RETURN -1;

  ELSIF (NOT _p.usr_active) THEN
    IF(SELECT metric_value='AdminOnly'
         FROM metric
        WHERE metric_name='AllowedUserLogins') THEN
      RETURN -3;
    END IF;
    RETURN -2;
  END IF;

  IF EXISTS(SELECT 1
              FROM pg_proc
              JOIN pg_namespace ON (pronamespace=pg_namespace.oid)
             WHERE nspname='public'
               AND proname='buildsearchpath') THEN
    EXECUTE 'SET SEARCH_PATH TO ' || public.buildSearchPath();
  END IF;

  RETURN 1;

END;

Function: public.logout()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  PERFORM pg_advisory_unlock(datid::integer, procpid)
     FROM pg_stat_activity
    WHERE(procpid = pg_backend_pid());

  RETURN 0;
END;

Function: public.lowercost(integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid	ALIAS FOR $1;
  pCosttype	ALIAS FOR $2;

BEGIN
    RETURN lowerCost(pItemid, pCosttype, TRUE);
END;

Function: public.lowercost(integer, text, boolean)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCosttype ALIAS FOR $2;
  pActual	ALIAS FOR $3;
  _type CHAR(1);
  _actCost	NUMERIC;
  _actCost1	NUMERIC;
  _actCost2	NUMERIC;
  _stdCost	NUMERIC;
  _stdCost1	NUMERIC;
  _stdCost2	NUMERIC;
  _cost		NUMERIC;
  _cost1	NUMERIC;
  _cost2	NUMERIC;
  _batchsize	NUMERIC;

BEGIN

  SELECT item_type INTO _type
  FROM item
  WHERE (item_id=pItemid);

  _batchsize := COALESCE( (
    SELECT bomhead_batchsize
    FROM bomhead
    WHERE ((bomhead_item_id=pItemId)
     AND  (bomhead_rev_id=getActiveRevId('BOM',pItemId))) LIMIT 1), 1);

  -- find the lowercost in the base currency at the current conversion rate
  IF (_type IN ('M', 'F', 'B', 'T')) THEN

    IF (pActual) THEN
      SELECT SUM( CASE WHEN (bomitemcost_id IS NOT NULL AND bc.costelem_id IS NOT NULL) THEN
                  round(currToBase(bomitemcost_curr_id, bomitemcost_actcost, CURRENT_DATE),6) * itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL, (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap))
                  ELSE
                  round(currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE),6) * itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL, (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap))
                  END )
	  INTO _cost
      FROM bomitem(pItemid)
        JOIN item ON (item_id=bomitem_item_id AND item_type <> 'T')
        JOIN itemcost ON (itemcost_item_id=bomitem_item_id)
        JOIN costelem ic ON (ic.costelem_id=itemcost_costelem_id AND ic.costelem_type=pCosttype)
        LEFT OUTER JOIN bomitemcost ON (bomitemcost_bomitem_id=bomitem_id)
        LEFT OUTER JOIN costelem bc ON (bc.costelem_id=bomitemcost_costelem_id AND bc.costelem_type=pCosttype)
      WHERE ( CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1) );
    ELSE
      SELECT SUM( itemcost_stdcost * itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL, (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap)) )
	  INTO _cost
      FROM bomitem(pItemid)
        JOIN item ON (item_id=bomitem_item_id AND item_type <> 'T')
        JOIN itemcost ON (itemcost_item_id=bomitem_item_id)
        JOIN costelem ON (costelem_id=itemcost_costelem_id AND costelem_type=pCosttype)
      WHERE ( CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1) ); 
    END IF;
    
    IF (NOT FOUND) THEN
      _cost := NULL;
    END IF;

  ELSIF (_type IN ('C')) THEN
    SELECT SUM(CASE WHEN (bbomitem_qtyper = 0) THEN 0
                    ELSE currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) / bbomitem_qtyper * bbomitem_costabsorb
               END),
	   SUM(CASE WHEN (bbomitem_qtyper = 0) THEN 0
                    ELSE itemcost_stdcost / bbomitem_qtyper * bbomitem_costabsorb
               END)
	INTO _actCost1, _stdCost1
    FROM itemcost
         JOIN costelem       ON (itemcost_costelem_id=costelem_id)
         JOIN xtmfg.bbomitem ON (bbomitem_parent_item_id=itemcost_item_id)
    WHERE ( (bbomitem_item_id=pItemid)
     AND (CURRENT_DATE BETWEEN bbomitem_effective AND (bbomitem_expires - 1))
     AND (costelem_type=pCosttype) );

    SELECT SUM(CASE WHEN (t.bbomitem_qtyper = 0) THEN 0
                    ELSE currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) * s.bbomitem_qtyper / t.bbomitem_qtyper * t.bbomitem_costabsorb
               END),
	   SUM(CASE WHEN (t.bbomitem_qtyper = 0) THEN 0
                    ELSE itemcost_stdcost * s.bbomitem_qtyper / t.bbomitem_qtyper * t.bbomitem_costabsorb
               END)
	INTO _actCost2, _stdCost2
    FROM costelem
         JOIN itemcost            ON (costelem_id=itemcost_costelem_id)
         JOIN xtmfg.bbomitem AS s ON (itemcost_item_id=s.bbomitem_item_id)
         JOIN xtmfg.bbomitem AS t ON (s.bbomitem_parent_item_id=t.bbomitem_parent_item_id)
         JOIN  item               ON (s.bbomitem_item_id=item_id)
    WHERE ( (t.bbomitem_item_id=pItemid)
     AND ( CURRENT_DATE BETWEEN s.bbomitem_effective
                        AND (s.bbomitem_expires - 1) )
     AND ( CURRENT_DATE BETWEEN t.bbomitem_effective
                        AND (t.bbomitem_expires - 1) )
     AND (item_type='Y')
     AND (costelem_type=pCosttype) );

    IF (pActual) THEN
	_cost  = _actCost;
	_cost1 = _actCost1;
	_cost2 = _actCost2;
    ELSE
	_cost  = _stdCost;
	_cost1 = _stdCost1;
	_cost2 = _stdCost2;	-- should this be std or act?
    END IF;

    IF (_cost1 IS NULL AND _cost2 IS NULL) THEN
	_cost = NULL;
    ELSE
        _cost = COALESCE(_cost1, 0) + COALESCE(_cost2, 0);
    END IF;

  ELSE
    RETURN NULL;
  END IF;

  RETURN round(_cost,6);

END;

Function: public.maintainbomworkspace()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _test TEXT;

BEGIN

  SELECT tablename INTO _test
  FROM pg_tables
  WHERE (tablename='bomwork');
  IF (NOT FOUND) THEN
    CREATE TEMPORARY TABLE bomwork
    ( bomwork_id INTEGER, bomwork_set_id INTEGER, bomwork_parent_id INTEGER,
      bomwork_seqnumber INTEGER, bomwork_parent_seqnumber INTEGER,
      bomwork_item_id INTEGER, bomwork_item_type CHARACTER(1), bomwork_status CHARACTER(1),
      bomwork_qtyper NUMERIC(20, 8), bomwork_scrap NUMERIC(20, 10),
      bomwork_level INTEGER, bomwork_effective DATE, bomwork_expires DATE,
      bomwork_stdunitcost NUMERIC(16, 4), bomwork_actunitcost NUMERIC(16, 4),
      bomwork_createwo BOOLEAN, bomwork_issuemethod CHARACTER(1) );
    CREATE INDEX bomwork_set_id_idx ON bomwork(bomwork_set_id);
  END IF;

  RETURN 1;

END;

Function: public.markapcheckasposted(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'markAPCheckAsPosted() is deprecated - use markCheckAsPosted() instead';
  RETURN markCheckAsPosted($1);

END;

Function: public.markapcheckasprinted(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'markAPCheckAsPrinted() is deprecated - use markCheckAsPrinted()';
  RETURN markCheckAsPrinted($1);
END;

Function: public.markcheckasposted(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid ALIAS FOR $1;

BEGIN

  UPDATE checkhead
  SET checkhead_posted=TRUE
  WHERE (checkhead_id=pCheckid);

  RETURN 1;

END;

Function: public.markcheckasprinted(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid ALIAS FOR $1;

BEGIN

  UPDATE checkhead
  SET checkhead_printed=TRUE
  WHERE (checkhead_id=pCheckid);

  RETURN 1;

END;

Function: public.massexpirebomitem(integer, date, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pExpireDate ALIAS FOR $2;
  pECN ALIAS FOR $3;

BEGIN

  UPDATE bomitem
  SET bomitem_expires=pExpireDate
  WHERE ( (bomitem_expires >= CURRENT_DATE)
   AND (bomitem_item_id=pItemid)
   AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id)) );

  RETURN TRUE;
END;

Function: public.massreplacebomitem(integer, integer, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNewItemid ALIAS FOR $1;
  pOriginalItemid ALIAS FOR $2;
  pEffectiveDate ALIAS FOR $3;
  pECN ALIAS FOR $4;
  _effectiveDate DATE;
  _result		INTEGER;

BEGIN

  _effectiveDate := COALESCE(pEffectiveDate, CURRENT_DATE);

  IF (BOMContains(pOriginalItemid, pNewItemid) OR
      BOMContains(pNewItemid, pOriginalItemid)) THEN
    RETURN -1;
  END IF;

  INSERT INTO bomitem
  ( bomitem_parent_item_id, bomitem_seqnumber,
    bomitem_item_id, bomitem_qtyfxd, bomitem_qtyper, bomitem_uom_id,
    bomitem_scrap, bomitem_effective, bomitem_expires, bomitem_ecn,
    bomitem_createwo, bomitem_issuemethod, bomitem_subtype,
    bomitem_booitem_seq_id, bomitem_schedatwooper, bomitem_moddate, bomitem_rev_id,
    bomitem_char_id, bomitem_value )
  SELECT bomitem_parent_item_id, bomitem_seqnumber,
         pNewItemid, bomitem_qtyfxd, bomitem_qtyper, bomitem_uom_id,
         bomitem_scrap, _effectiveDate, endOfTime(), pECN,
         bomitem_createwo, bomitem_issuemethod, 'I',
         bomitem_booitem_seq_id, bomitem_schedatwooper, CURRENT_DATE, getActiveRevId('BOM',bomitem_parent_item_id),
         bomitem_char_id, bomitem_value
  FROM bomitem
  WHERE ( (_effectiveDate < bomitem_expires)
   AND (bomitem_item_id=pOriginalItemid)
   AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id)) );

  UPDATE bomitem
  SET bomitem_expires=_effectiveDate
  WHERE ( (_effectiveDate < bomitem_expires)
   AND (bomitem_item_id=pOriginalItemid)
   AND (bomitem_rev_id=getActiveRevid('BOM',bomitem_parent_item_id)) );

  RETURN 1;
END;

Function: public.merge2crmaccts(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

This function merges two crmacct records as decribed in crmacctsel records. For each field in the crmacctsel record marked TRUE, the data are copied from the crmacct record with crmacct_id=pSourceId to the record with crmacct_id=pTargetId. If the purge argument is TRUE, the source record is deleted. If it is FALSE, then mrgundo records are created so the merge can later be undone.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceId ALIAS FOR $1;
  pTargetId ALIAS FOR $2;
  _purge    BOOLEAN := COALESCE($3, FALSE);

  _coldesc    RECORD;
  _count      INTEGER := 0;
  _hassubtype BOOLEAN;
  _mrgcol     BOOLEAN;
  _result     INTEGER := 0;
  _sel        RECORD;
  _colname    TEXT;
  _tmpid      INTEGER;

BEGIN
  -- Validate
  IF (pSourceId = pTargetId) THEN
    RAISE NOTICE 'Tried to merge a CRM Account with itself: %.', pSourceId;
    RETURN 0;
  ELSIF (pSourceId IS NULL) THEN
    RAISE EXCEPTION 'Merge source id cannot be null [xtuple: merge, -1]';
  ELSIF NOT(EXISTS(SELECT 1 FROM crmacct WHERE crmacct_id=pSourceId)) THEN
    RAISE EXCEPTION 'Merge source % not found [xtuple: merge, -2, %]',
                    pSourceId, pSourceId;
  ELSIF (pTargetId IS NULL) THEN
    RAISE EXCEPTION 'Merge target id cannot be null [xtuple: merge, -3]';
  ELSIF NOT(EXISTS(SELECT 1 FROM crmacct WHERE crmacct_id=pTargetId)) THEN
    RAISE EXCEPTION 'Merge target % not found [xtuple: merge, -4, %]',
                    pTargetId, pTargetId;
  ELSIF NOT(EXISTS(SELECT 1
                     FROM crmacctsel
                    WHERE (crmacctsel_src_crmacct_id=pSourceId)
                      AND (crmacctsel_dest_crmacct_id=pTargetId))) THEN
    RAISE EXCEPTION 'Source % and target % have not been selected for merging [xtuple: merge, -5, %, %]',
                    pSourceId, pTargetId, pSourceId, pTargetId;
  END IF;

  _result:= changeFkeyPointers('public', 'crmacct', pSourceId, pTargetId,
                               ARRAY[ 'crmacctsel', 'crmacctmrgd' ], _purge)
          + changePseudoFKeyPointers('public', 'alarm', 'alarm_source_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'alarm_source', 'CRMA', _purge)
          + changePseudoFKeyPointers('public', 'charass', 'charass_target_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'charass_target_type', 'CRMACCT', _purge)
          + changePseudoFKeyPointers('public', 'comment', 'comment_source_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'comment_source', 'CRMA', _purge)
          + changePseudoFKeyPointers('public', 'docass', 'docass_source_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'docass_source_type', 'CRMA', _purge)
          + changePseudoFKeyPointers('public', 'docass', 'docass_target_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'docass_target_type', 'CRMA', _purge)
          + changePseudoFKeyPointers('public', 'imageass', 'imageass_source_id',
                                     pSourceId, 'public', 'crmacct', pTargetId,
                                     'imageass_source', 'CRMA', _purge)
          ;

  -- TODO: find a generic way to handle pseudofkeys in packages - see 9401
  IF (fetchMetricBool('EnableBatchManager') AND packageIsEnabled('xtbatch')) THEN
    _result:= _result
            + changePseudoFKeyPointers('xtbatch', 'emlassc', 'emlassc_assc_id',
                                       pSourceId, 'public', 'crmacct', pTargetId,
                                       'emlassc_type', 'CRMA', _purge);
  END IF;

  -- back up all of the values in the target record that are about to be changed
  FOR _coldesc IN SELECT attname, typname
                    FROM pg_attribute
                    JOIN pg_type      ON (atttypid=pg_type.oid)
                    JOIN pg_class     ON (attrelid=pg_class.oid)
                    JOIN pg_namespace ON (relnamespace=pg_namespace.oid)
                   WHERE (attnum >= 0)
                     AND (relname='crmacct')
                     AND (nspname='public')
                     AND (attname NOT IN ('crmacct_id', 'crmacct_number'))
  LOOP

    -- if we're supposed to merge this column at all
    EXECUTE 'SELECT ' || quote_ident('crmacctsel_mrg_' || _coldesc.attname) || '
               FROM crmacctsel
              WHERE ((crmacctsel_src_crmacct_id='  || pSourceId || ')
                 AND (crmacctsel_dest_crmacct_id=' || pTargetId || '))' INTO _mrgcol;

    IF (_mrgcol) THEN
      _colname := REPLACE(_coldesc.attname, 'crmacctsel_mrg_', '');

      -- optionally back up the old value from the destination
      -- we'll back up the old value from the source further down
      IF (NOT _purge) THEN
        BEGIN
          EXECUTE 'INSERT INTO mrgundo (
                       mrgundo_schema,      mrgundo_table,
                       mrgundo_pkey_col,    mrgundo_pkey_id,
                       mrgundo_col,         mrgundo_value,      mrgundo_type,
                       mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
                 ) SELECT ''public'',     ''crmacct'',
                          ''crmacct_id'', crmacct_id, '   ||
                          quote_literal(_colname)         || ', ' ||
                          quote_ident(_colname)           || ', ' ||
                          quote_literal(_coldesc.typname) || ',
                          ''public'', ''crmacct'', crmacct_id
                     FROM crmacct
                    WHERE (crmacct_id=' || pTargetId || ');' ;
        EXCEPTION WHEN unique_violation THEN
          RAISE EXCEPTION 'Could not make a backup copy of % when merging % into % [xtuple: merge, -8, %, %, public, crmacct, %]',
                       _colname, pSourceId, pTargetId,
                       _colname, pSourceId, pTargetId;
        END;
      END IF;

      -- TODO: what do we do about users?
      /* update the destination crmacct in one of 3 different ways:
         - crmacct_notes might be concatenated from more than one source record
	 - foreign keys to crm account subtype records (e.g. crmacct_cust_id)
           must not leave orphaned records and must avoid uniqueness violations
         - some fields can simply be updated in place
       */
      IF (_colname = 'crmacct_notes') THEN
        EXECUTE 'UPDATE crmacct dest
                    SET '      || quote_ident(_colname) ||
                      '=dest.' || quote_ident(_colname) ||
                      E' || E''\\n'' || src.' || _colname || '
                  FROM crmacct src
                  JOIN crmacctsel ON (src.crmacct_id=crmacctsel_src_crmacct_id)
                 WHERE ((dest.crmacct_id=crmacctsel_dest_crmacct_id)
                    AND (dest.crmacct_id!=crmacctsel_src_crmacct_id));';

      ELSIF (_colname IN ('crmacct_cust_id', 'crmacct_prospect_id', 
                          'crmacct_vend_id', 'crmacct_taxauth_id',
                          'crmacct_emp_id',  'crmacct_salesrep_id')) THEN
        IF (_colname IN ('crmacct_cust_id', 'crmacct_prospect_id')) THEN
          EXECUTE 'SELECT src.' || quote_ident(_colname) || ' IS NOT NULL
                      AND (dest.crmacct_prospect_id IS NOT NULL OR
                           dest.crmacct_cust_id IS NOT NULL)
                     FROM crmacct src
                     JOIN crmacctsel ON (src.crmacct_id=crmacctsel_src_crmacct_id)
                     JOIN crmacct dest ON (crmacctsel_dest_crmacct_id=dest.crmacct_id)
                    WHERE ((src.crmacct_id='  || pSourceId || ')
                       AND (dest.crmacct_id=' || pTargetId || '))' INTO _hassubtype;
          IF (_hassubtype) THEN
            RAISE EXCEPTION 'Cannot merge two CRM Accounts that both refer to Customers and/or Prospects [xtuple: merge, -6, %, %]',
                            pSourceId, pTargetId;
          END IF;
        ELSE
          EXECUTE 'SELECT src.' || quote_ident(_colname) || ' IS NOT NULL
                      AND dest.'|| quote_ident(_colname) || ' IS NOT NULL
                     FROM crmacct src
                     JOIN crmacctsel ON (src.crmacct_id=crmacctsel_src_crmacct_id)
                     JOIN crmacct dest ON (crmacctsel_dest_crmacct_id=dest.crmacct_id)
                    WHERE ((src.crmacct_id='  || pSourceId || ')
                       AND (dest.crmacct_id=' || pTargetId || '))' INTO _hassubtype;

          IF (_hassubtype) THEN
            RAISE EXCEPTION 'Cannot merge CRM Accounts until the % child records have been merged [xtuple: merge, -7, %, %, %]',
                            _colname, _colname, pSourceId, pTargetId;
          END IF;

        END IF;

        /* clearing the source separately from setting the target avoids
           problems with triggers updating the wrong records */
        EXECUTE 'SELECT ' || quote_ident(_colname) || ' FROM crmacct
                  WHERE crmacct_id=' || pSourceId
        INTO _tmpid;

        -- now we have the data to back up the source
        IF (NOT _purge) THEN
          BEGIN
            EXECUTE 'INSERT INTO mrgundo (
                         mrgundo_schema,      mrgundo_table,
                         mrgundo_pkey_col,    mrgundo_pkey_id,
                         mrgundo_col,         mrgundo_value,      mrgundo_type,
                         mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
                   ) SELECT ''public'',     ''crmacct'',
                            ''crmacct_id'', crmacct_id, '   ||
                            quote_literal(_colname)         || ', ' ||
                            quote_ident(_colname)           || ', ' ||
                            quote_literal(_coldesc.typname) || ',
                            ''public'', ''crmacct'', '      || pTargetId || '
                       FROM crmacct
                      WHERE (crmacct_id=' || pSourceId || ');' ;
          EXCEPTION WHEN unique_violation THEN
            RAISE EXCEPTION 'Could not make a backup copy of % when merging % into % [xtuple: merge, -8, %, %, public, crmacct, %]',
                         _colname, pSourceId, pTargetId,
                         _colname, pSourceId, pTargetId;
          END;
        END IF;

        EXECUTE 'UPDATE crmacct SET ' || quote_ident(_colname) || '=NULL
              WHERE (crmacct_id=' || pSourceId || ');';

        EXECUTE 'UPDATE crmacct
                    SET ' || quote_ident(_colname) || '=' || quote_literal(_tmpid) || '
              WHERE (crmacct_id=' || pTargetId || ');';

      ELSE
        EXECUTE 'UPDATE crmacct dest
                    SET '      || quote_ident(_colname) || '
                        =src.' || quote_ident(_colname) || '
                  FROM crmacct src
                 WHERE ((dest.crmacct_id=' || pTargetId || ')
                    AND (src.crmacct_id='  || pSourceId || '));';
      END IF;

      GET DIAGNOSTICS _count = ROW_COUNT;
      _result := _result + _count;
    END IF;

  END LOOP;

  IF (_purge) THEN
    DELETE FROM crmacct WHERE crmacct = pSourceId;
  ELSE
    INSERT INTO mrgundo (
           mrgundo_schema,      mrgundo_table,
           mrgundo_pkey_col,    mrgundo_pkey_id,
           mrgundo_col,         mrgundo_value,      mrgundo_type,
           mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
    ) SELECT 'public',         'crmacct',
             'crmacct_id',     pSourceId,
             'crmacct_active', crmacct_active, 'bool',
             'public',         'crmacct',       pTargetId
        FROM crmacct
       WHERE crmacct_active AND (crmacct_id = pSourceId);
    GET DIAGNOSTICS _count = ROW_COUNT;
    IF (_count > 0) THEN
      _result := _result + _count;
      UPDATE crmacct SET crmacct_active = false WHERE (crmacct_id=pSourceId);
    END IF;

    -- make a special record of the source crm account so we can delete it later
    INSERT INTO mrgundo (
           mrgundo_schema,      mrgundo_table,
           mrgundo_pkey_col,    mrgundo_pkey_id,
           mrgundo_col,         mrgundo_value,      mrgundo_type,
           mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id
     ) VALUES (
           'public',     'crmacct',
           'crmacct_id', pSourceId,
           NULL,         NULL,       NULL,
           'public',     'crmacct', pTargetId);
  END IF;

  DELETE FROM crmacctsel WHERE (crmacctsel_src_crmacct_id=pSourceId);

  RETURN _result;
END;

Function: public.mergecrmaccts(integer, boolean)

Returns: integer

Language: PLPGSQL

This function uses the crmacctsel table to merge multiple crmacct records together. Only the merges into the specified target account are performed. Most of the work is done by repeated calls to the merge2crmaccts function. If the purge argument is FALSE, data are kept to allow reversing the merge.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetId     ALIAS FOR $1;
  _purge        BOOLEAN := COALESCE($2, FALSE);

  _retval       INTEGER;
BEGIN

  /* if crmacctsel says the target should not keep its original
     notes, clear them.  notes are special because the merge allows
     concatenating them from multiple sources. this needs to be
     kept in sync with merge2crmaccts' similar check.
   */
  IF NOT (SELECT crmacctsel_mrg_crmacct_notes
            FROM crmacctsel
           WHERE crmacctsel_src_crmacct_id=crmacctsel_dest_crmacct_id
             AND crmacctsel_dest_crmacct_id=pTargetId) THEN
    IF (NOT _purge) THEN
      INSERT INTO mrgundo (
             mrgundo_schema,      mrgundo_table,
             mrgundo_pkey_col,    mrgundo_pkey_id,
             mrgundo_col,         mrgundo_value,      mrgundo_type,
             mrgundo_base_schema, mrgundo_base_table, mrgundo_base_id)
      SELECT 'public', 'crmacct', crmacct_id,
             'public', 'crmacct', 'crmacct_id', crmacct_id,
             'crmacct_notes', crmacct_notes, 'text',
             'public', 'crmacct', crmacct_id
        FROM crmacct
       WHERE (crmacct_id=pTargetId);
    END IF;

    UPDATE crmacct
       SET crmacct_notes = ''
     WHERE (crmacct_id=pTargetId);
  END IF;

  -- merge the data from the various source records
  SELECT SUM(merge2crmaccts(crmacctsel_src_crmacct_id, pTargetId, _purge))
         INTO _retval
    FROM crmacctsel
   WHERE ((crmacctsel_dest_crmacct_id=pTargetId)
      AND (crmacctsel_dest_crmacct_id!=crmacctsel_src_crmacct_id));

  DELETE FROM crmacctsel WHERE crmacctsel_dest_crmacct_id=pTargetId;

  RETURN COALESCE(_retval, 0);

END;

Function: public.movebomitemdown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  _nextBomitem RECORD;

BEGIN

  SELECT nextbomitem.bomitem_seqnumber AS next_seqnumber,
         thisbomitem.bomitem_seqnumber AS this_seqnumber,
         thisbomitem.bomitem_parent_item_id AS parent_item_id,
         thisbomitem.bomitem_rev_id AS rev_id
          INTO _nextBomitem
  FROM bomitem AS nextbomitem, bomitem AS thisbomitem
  WHERE ((nextbomitem.bomitem_seqnumber > thisbomitem.bomitem_seqnumber)
   AND (nextbomitem.bomitem_parent_item_id=thisbomitem.bomitem_parent_item_id)
   AND (nextbomitem.bomitem_rev_id=thisbomitem.bomitem_rev_id)
   AND (thisbomitem.bomitem_id=pBomitemid))
  ORDER BY next_seqnumber
  LIMIT 1;

  IF (FOUND) THEN
--  Swap the seqnumber of the current bomitem and the next bomitem
--  There is the potential for multiple bomitems with the same seqnumber

    UPDATE bomitem
    SET bomitem_seqnumber=0
    WHERE (bomitem_seqnumber=_nextBomitem.next_seqnumber)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);

    UPDATE bomitem 
    SET bomitem_seqnumber=_nextBomitem.next_seqnumber
    WHERE (bomitem_seqnumber=_nextBomitem.this_seqnumber)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);

    UPDATE bomitem
    SET bomitem_seqnumber=_nextBomitem.this_seqnumber
    WHERE (bomitem_seqnumber=0)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);
  END IF;

  RETURN 1;

END;

Function: public.movebomitemup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  _nextBomitem RECORD;

BEGIN

  SELECT nextbomitem.bomitem_seqnumber AS next_seqnumber,
         thisbomitem.bomitem_seqnumber AS this_seqnumber,
         thisbomitem.bomitem_parent_item_id AS parent_item_id,
         thisbomitem.bomitem_rev_id AS rev_id
          INTO _nextBomitem
  FROM bomitem AS nextbomitem, bomitem AS thisbomitem
  WHERE ((nextbomitem.bomitem_seqnumber < thisbomitem.bomitem_seqnumber)
   AND (nextbomitem.bomitem_parent_item_id=thisbomitem.bomitem_parent_item_id)
   AND (nextbomitem.bomitem_rev_id=thisbomitem.bomitem_rev_id)
   AND (thisbomitem.bomitem_id=pBomitemid))
  ORDER BY next_seqnumber DESC
  LIMIT 1;

  IF (FOUND) THEN
--  Swap the seqnumber of the current bomitem and the next bomitem
--  There is the potential for multiple bomitems with the same seqnumber

    UPDATE bomitem
    SET bomitem_seqnumber=0
    WHERE (bomitem_seqnumber=_nextBomitem.next_seqnumber)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);

    UPDATE bomitem 
    SET bomitem_seqnumber=_nextBomitem.next_seqnumber
    WHERE (bomitem_seqnumber=_nextBomitem.this_seqnumber)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);

    UPDATE bomitem
    SET bomitem_seqnumber=_nextBomitem.this_seqnumber
    WHERE (bomitem_seqnumber=0)
      AND (bomitem_parent_item_id=_nextBomitem.parent_item_id)
      AND (bomitem_rev_id=_nextBomitem.rev_id);
  END IF;

  RETURN 1;

END;

Function: public.moveccarddown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCcardid ALIAS FOR $1;
  _nextCcard RECORD;

BEGIN

  SELECT nextCcard.ccard_id, nextCcard.ccard_seq AS next_seqnumber,
         thisCcard.ccard_seq AS this_seqnumber INTO _nextCcard
  FROM Ccard AS nextCcard, Ccard AS thisCcard
  WHERE ((nextCcard.ccard_seq > thisCcard.ccard_seq)
   AND (nextCcard.ccard_cust_id=thisCcard.ccard_cust_id)
   AND (thisCcard.ccard_id=pCcardid))
  ORDER BY next_seqnumber
  LIMIT 1;

  IF (FOUND) THEN
--  Swap the seqnumber of the current Ccard and the next Ccard

    UPDATE Ccard
    SET ccard_seq=_nextCcard.next_seqnumber
    WHERE (ccard_id=pCcardid);

    UPDATE Ccard
    SET ccard_seq=_nextCcard.this_seqnumber
    WHERE (ccard_id=_nextCcard.ccard_id);
  END IF;

  RETURN 1;

END;

Function: public.moveccardup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCcardid ALIAS FOR $1;
  _nextCcard RECORD;

BEGIN

  SELECT nextCcard.ccard_id AS ccard_id, nextCcard.ccard_seq AS next_seqnumber,
         thisCcard.ccard_seq AS this_seqnumber INTO _nextCcard
  FROM ccard AS nextCcard, ccard AS thisCcard
  WHERE ((nextCcard.ccard_seq < thisCcard.ccard_seq)
   AND (nextCcard.ccard_cust_id=thisCcard.ccard_cust_id)
   AND (thisCcard.ccard_id=pCcardid))
  ORDER BY next_seqnumber DESC
  LIMIT 1;

  IF (FOUND) THEN
--  Swap the seqnumber of the current Ccard and the next Ccard

    UPDATE Ccard 
    SET ccard_seq=_nextCcard.next_seqnumber
    WHERE (ccard_id=pCcardid);

    UPDATE Ccard
    SET ccard_seq=_nextCcard.this_seqnumber
    WHERE (ccard_id=_nextCcard.ccard_id);
  END IF;

  RETURN 1;

END;

Function: public.moveflgroupdown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlgrpid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flgrp_id AS id,
         flgrp_flhead_id AS flhead_id,
         flgrp_flgrp_id AS flgrp_id,
         flgrp_order AS ord INTO _from
    FROM flgrp
   WHERE (flgrp_id=pFlgrpid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord > _from.ord)
   ORDER BY ord
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flgrp
       SET flgrp_order=_to.ord
     WHERE (flgrp_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.moveflgroupup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlgrpid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flgrp_id AS id,
         flgrp_flhead_id AS flhead_id,
         flgrp_flgrp_id AS flgrp_id,
         flgrp_order AS ord INTO _from
    FROM flgrp
   WHERE (flgrp_id=pFlgrpid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord < _from.ord)
   ORDER BY ord DESC
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flgrp
       SET flgrp_order=_to.ord
     WHERE (flgrp_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.moveflitemdown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlitemid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flitem_id AS id,
         flitem_flhead_id AS flhead_id,
         flitem_flgrp_id AS flgrp_id,
         flitem_order AS ord INTO _from
    FROM flitem
   WHERE (flitem_id=pFlitemid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord > _from.ord)
   ORDER BY ord
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flitem
       SET flitem_order=_to.ord
     WHERE (flitem_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.moveflitemup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlitemid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flitem_id AS id,
         flitem_flhead_id AS flhead_id,
         flitem_flgrp_id AS flgrp_id,
         flitem_order AS ord INTO _from
    FROM flitem
   WHERE (flitem_id=pFlitemid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord < _from.ord)
   ORDER BY ord DESC
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flitem
       SET flitem_order=_to.ord
     WHERE (flitem_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.moveflspecdown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlspecid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flspec_id AS id,
         flspec_flhead_id AS flhead_id,
         flspec_flgrp_id AS flgrp_id,
         flspec_order AS ord INTO _from
    FROM flspec
   WHERE (flspec_id=pFlspecid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord > _from.ord)
   ORDER BY ord
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flspec
       SET flspec_order=_to.ord
     WHERE (flspec_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.moveflspecup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pFlspecid ALIAS FOR $1;
  _from RECORD;
  _to RECORD;

BEGIN

  SELECT flspec_id AS id,
         flspec_flhead_id AS flhead_id,
         flspec_flgrp_id AS flgrp_id,
         flspec_order AS ord INTO _from
    FROM flspec
   WHERE (flspec_id=pFlspecid);
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  SELECT id, type, ord INTO _to
    FROM (SELECT flitem_id AS id, 'I' AS type, flitem_order AS ord
            FROM flitem
           WHERE ((flitem_flgrp_id=_from.flgrp_id)
             AND  (flitem_flhead_id=_from.flhead_id))
           UNION
          SELECT flgrp_id AS id, 'G' AS type, flgrp_order AS ord
            FROM flgrp
           WHERE ((flgrp_flgrp_id=_from.flgrp_id)
             AND  (flgrp_flhead_id=_from.flhead_id))
           UNION
          SELECT flspec_id AS id, 'S' AS type, flspec_order AS ord
            FROM flspec
           WHERE ((flspec_flgrp_id=_from.flgrp_id)
             AND  (flspec_flhead_id=_from.flhead_id)) ) AS data
   WHERE (ord < _from.ord)
   ORDER BY ord DESC
   LIMIT 1;
  IF (FOUND) THEN
    UPDATE flspec
       SET flspec_order=_to.ord
     WHERE (flspec_id=_from.id);

    IF (_to.type='I') THEN
      UPDATE flitem
         SET flitem_order=_from.ord
       WHERE (flitem_id=_to.id);
    ELSE
      IF (_to.type='G') THEN
        UPDATE flgrp
           SET flgrp_order=_from.ord
         WHERE (flgrp_id=_to.id);
      ELSE
        IF (_to.type='S') THEN
          UPDATE flspec
             SET flspec_order=_from.ord
           WHERE (flspec_id=_to.id);
        END IF;
      END IF;
    END IF;
  END IF;

  RETURN 0;

END;

Function: public.movescript(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pscriptid ALIAS FOR $1;
  poldpkgid ALIAS FOR $2;
  pnewpkgid ALIAS FOR $3;

  _deletestr    TEXT;
  _destination  TEXT;
  _insertstr    TEXT;
  _rows         INTEGER;
  _selectstr    TEXT;
  _source       TEXT;
  _record       RECORD;

BEGIN
  IF (poldpkgid = pnewpkgid) THEN
    RETURN 0;
  END IF;

  IF (poldpkgid = -1) THEN
    _source = 'public.script';
  ELSE
    SELECT pkghead_name || '.pkgscript' INTO _source
    FROM pkghead
    WHERE pkghead_id=poldpkgid;

    IF NOT FOUND THEN
      RETURN -1;
    END IF;
  END IF;

  IF (pnewpkgid = -1) THEN
    _destination = 'public.script';
  ELSE
    SELECT pkghead_name || '.pkgscript' INTO _destination
    FROM pkghead
    WHERE pkghead_id=pnewpkgid;

    IF NOT FOUND THEN
      RETURN -2;
    END IF;
  END IF;

  _selectstr := ' SELECT * FROM ' || _source ||
                ' WHERE script_id = ' || pscriptid;
  EXECUTE _selectstr INTO _record;

  _deletestr := 'DELETE FROM ONLY ' || _source || 
                ' WHERE script_id = ' || pscriptid;
  EXECUTE _deletestr;
  GET DIAGNOSTICS _rows = ROW_COUNT;
  RAISE NOTICE '% rows from %', _rows, _deletestr;
  IF (_rows < 1) THEN
    RETURN -3;
  ELSIF (_rows > 1) THEN
    RAISE EXCEPTION 'Tried to delete % scripts with the id % when there should be exactly 1',
                    _rows, pscriptid;
  END IF;

  _insertstr := 'INSERT INTO ' || _destination ||
                ' (script_id, script_name, script_order, script_enabled, ' ||
                '  script_source, script_notes) VALUES ('
                || _record.script_id      || ','
                || quote_literal(_record.script_name)    || ','
                || _record.script_order   || ','
                || _record.script_enabled || ','
                || quote_literal(_record.script_source)  || ','
                || quote_literal(_record.script_notes )  || ');'
                ;
  EXECUTE _insertstr;
  GET DIAGNOSTICS _rows = ROW_COUNT;
  RAISE NOTICE '% rows from %', _rows, _insertstr;
  IF (_rows < 1) THEN
    RETURN -4;
  ELSIF (_rows > 1) THEN
    RAISE EXCEPTION 'Tried to insert % scripts with the id % when there should be exactly 1',
                    _rows, pscriptid;
  END IF;

  RETURN pscriptid;

END;

Function: public.moveuiform(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  puiformid ALIAS FOR $1;
  poldpkgid ALIAS FOR $2;
  pnewpkgid ALIAS FOR $3;

  _deletestr    TEXT;
  _destination  TEXT;
  _insertstr    TEXT;
  _rows         INTEGER;
  _selectstr    TEXT;
  _source       TEXT;
  _record       RECORD;

BEGIN
  IF (poldpkgid = pnewpkgid) THEN
    RETURN 0;
  END IF;

  IF (poldpkgid = -1) THEN
    _source = 'public.uiform';
  ELSE
    SELECT pkghead_name || '.pkguiform' INTO _source
    FROM pkghead
    WHERE pkghead_id=poldpkgid;

    IF NOT FOUND THEN
      RETURN -1;
    END IF;
  END IF;

  IF (pnewpkgid = -1) THEN
    _destination = 'public.uiform';
  ELSE
    SELECT pkghead_name || '.pkguiform' INTO _destination
    FROM pkghead
    WHERE pkghead_id=pnewpkgid;

    IF NOT FOUND THEN
      RETURN -2;
    END IF;
  END IF;

  _selectstr := ' SELECT * FROM ' || _source ||
                ' WHERE uiform_id = ' || puiformid;
  EXECUTE _selectstr INTO _record;

  _deletestr := 'DELETE FROM ONLY ' || _source || 
                ' WHERE uiform_id = ' || puiformid;
  EXECUTE _deletestr;
  GET DIAGNOSTICS _rows = ROW_COUNT;
  RAISE NOTICE '% rows from %', _rows, _deletestr;
  IF (_rows < 1) THEN
    RETURN -3;
  ELSIF (_rows > 1) THEN
    RAISE EXCEPTION 'Tried to delete % uiforms with the id % when there should be exactly 1',
                    _rows, puiformid;
  END IF;

  _insertstr := 'INSERT INTO ' || _destination ||
                ' (uiform_id, uiform_name, uiform_order, uiform_enabled, ' ||
                '  uiform_source, uiform_notes) VALUES ('
                || _record.uiform_id      || ','
                || quote_literal(_record.uiform_name)    || ','
                || _record.uiform_order   || ','
                || _record.uiform_enabled || ','
                || quote_literal(_record.uiform_source)  || ','
                || quote_literal(_record.uiform_notes )  || ');'
                ;
  EXECUTE _insertstr;
  GET DIAGNOSTICS _rows = ROW_COUNT;
  RAISE NOTICE '% rows from %', _rows, _insertstr;
  IF (_rows < 1) THEN
    RETURN -4;
  ELSIF (_rows > 1) THEN
    RAISE EXCEPTION 'Tried to insert % uiforms with the id % when there should be exactly 1',
                    _rows, puiformid;
  END IF;

  RETURN puiformid;

END;

Function: public.moveupdown(pdir integer, pextra text, pjoincol text, pseqcol text, ptable text, pschema text, pid text)

Returns: integer

Language: PLPGSQL

moveUpDown moves a particular record up or down in an ordered list. pId argument names the record to move. pSchema (uses public if NULL) and pTable name the table holding the list. pSeqCol is the column that holds the sequence number. pJoinCol is the column that distinguishes one list from another in the same table, or NULL if the table holds only one list. pExtra is an extra join clause that may be required, or NULL. pDir is either UP, meaning move the pId record closer to the beginning, or DOWN. Returns the id of the record with which pId was swapped, or pId if the record was already at the end in the specified direction.

DECLARE
  _keyfield TEXT;
  _keysize  INTEGER;
  _qry      TEXT;
  _r        RECORD;
  _rowcnt   INTEGER;
  _schema   TEXT := COALESCE(pSchema, 'public');
BEGIN
  RAISE DEBUG 'moveUpDown(%, %, %, %, %, %, %) entered',
              pId, pSchema, pTable, pSeqCol, pJoinCol, pExtra, pDir;

  IF (UPPER(pDir) NOT IN ('UP', 'DOWN')) THEN
     RAISE EXCEPTION 'Cannot change the order of records; unsure what % means for sequencing [xtuple: moveUpDown, -1, %, %.%]',
                     pDir, pDir, _schema, pTable;
  END IF;

  SELECT attname, ARRAY_UPPER(conkey, 1) INTO _keyfield, _keysize
    FROM pg_attribute
    JOIN pg_constraint ON (attrelid=conrelid AND attnum=conkey[1])
    JOIN pg_class      ON (conrelid=pg_class.oid)
    JOIN pg_namespace  ON (relnamespace=pg_namespace.oid)
   WHERE ((contype='p')
      AND (nspname=_schema)
      AND (relname=pTable));

  RAISE DEBUG 'SELECT attname... returned %, %', _keyfield, _keysize;

  IF (_keysize > 1) THEN
    RAISE EXCEPTION 'Cannot change the order of records because %.% has a composite primary key [xtuple: moveUpDown, -2, %.%]',
                     _schema, pTable,
                     _schema, pTable;
  END IF;

  /* SELECT next._keyfield AS nextid,
            next.pSeqCol   AS nextseq,
            this.pSeqCol   AS thisseq
       FROM _schema.pTable AS next,
            _schema.pTable AS this
      WHERE (this._keyfield=$1)
          AND (next.pSeqCol [> or <] this.pSeqCol)
        [ AND (next.pJoinCol=this.pJoinCol) ]
        [ AND (pExtra) ]
      ORDER BY nextseq [ DESC or ASC ]
      LIMIT 1;
  */

  _qry := 'SELECT next.' || quote_ident(_keyfield) || ' AS nextid,
                  next.' || quote_ident(pSeqCol)   || ' AS nextseq,
                  this.' || quote_ident(pSeqCol)   || ' AS thisseq
             FROM ' || _schema || '.' || quote_ident(pTable) || ' AS next,
                  ' || _schema || '.' || quote_ident(pTable) || ' AS this
            WHERE ((this.' || quote_ident(_keyfield)  || '=$1)
               AND (next.' || quote_ident(pSeqCol)    ||
                    CASE pDir WHEN 'UP' THEN ' < ' ELSE ' > ' END ||
                   'this.' || quote_ident(pSeqCol) || ')' ||
               CASE WHEN pJoinCol IS NULL THEN ''
                    ELSE ' AND (next.' || quote_ident(pJoinCol)  ||
                         '=this.' || quote_ident(pJoinCol) || ')'
               END ||
          '     AND (' || COALESCE(pExtra, 'TRUE') || '))
            ORDER BY nextseq ' ||
               CASE pDir WHEN 'UP' THEN 'DESC' ELSE 'ASC' END ||
          ' LIMIT 1;';
  RAISE DEBUG 'moveUpDown about to use % when running %', pId, _qry;

  EXECUTE _qry INTO _r USING pId;
  GET DIAGNOSTICS _rowcnt = ROW_COUNT;
  RAISE DEBUG 'next id %, next seq %, this id %, this seq %',
               _r.nextid, _r.nextseq, pId, _r.thisseq;

  IF (_rowcnt > 0) THEN
    _qry := 'UPDATE ' || _schema || '.' || quote_ident(pTable)  ||
              ' SET ' || pSeqCol || '=CAST($1 AS INTEGER)
             WHERE (' || quote_ident(_keyfield) || '=$2);';

    EXECUTE _qry USING -1,         _r.nextid;
    EXECUTE _qry USING _r.nextseq, pId;
    EXECUTE _qry USING _r.thisseq, _r.nextid;
    RETURN _r.nextid;
  END IF;

  RETURN pId;
END;

Function: public.nextperiodbyinterval(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  pInterval ALIAS FOR $2;
  _periodid INTEGER;
BEGIN
  SELECT b.period_id INTO _periodid
    FROM period AS a, period AS b
   WHERE ((a.period_id=pPeriodid)
     AND  (b.period_start >= a.period_start))
   ORDER BY b.period_start
   LIMIT 1 OFFSET pInterval;
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;
  RETURN _periodid;
END;

Function: public.nextprsubnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrNumber ALIAS FOR $1;
  _subNumber INTEGER;

BEGIN

  SELECT MAX(pr_subnumber) INTO _subNumber
  FROM pr
  WHERE (pr_number=pPrNumber);

  IF (_subNumber IS NULL)
    THEN _subNumber := 0;
  END IF;

  RETURN (_subNumber + 1);

END;

Function: public.nextwosubnumber(integer)

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT COALESCE((MAX(wo_subnumber) + 1), 1)
FROM wo
WHERE (wo_number=($1));

Function: public.noneg(numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pValue ALIAS FOR $1;

BEGIN

  IF (pValue < 0) THEN
    RETURN 0;
  ELSE
   RETURN pValue;
  END IF;

END;

Function: public.nopos(numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pValue ALIAS FOR $1;

BEGIN

  IF (pValue > 0) THEN
    RETURN 0;
  ELSE
   RETURN pValue;
  END IF;

END;

Function: public.normalizetrialbal(integer, bpchar)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTrialbalid ALIAS FOR $1;
  pSide ALIAS FOR $2;
  _value NUMERIC;
  _r RECORD;

BEGIN

  SELECT accnt_type, trialbal_beginning, trialbal_ending INTO _r
  FROM trialbal, accnt
  WHERE ( (trialbal_accnt_id=accnt_id)
   AND (trialbal_id=pTrialbalid) );
  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

-- If we are looking for the Ending Balance, cache it
  IF (pSide = 'E') THEN
    _value = _r.trialbal_ending;

--  We had better been looking for the Beginning Balance!
  ELSE
    _value = _r.trialbal_beginning;
  END IF;

--  If the accnt_type is Asset or Expense, swap the sense
  IF (_r.accnt_type IN ('A', 'E')) THEN
    _value := (_value * -1);
  END IF;

  RETURN _value;

END;

Function: public.numofdatabaseusers()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _count INTEGER;

BEGIN

  SELECT count(*)
    INTO _count
    FROM pg_stat_activity, pg_locks
   WHERE((database=datid)
     AND (classid=datid)
     AND (objsubid=2)
     AND (procpid = pg_backend_pid()));
  IF (_count IS NULL) THEN
    _count := 0;
  END IF;

  RETURN _count;

END;

Function: public.numofserverusers()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _count INTEGER;

BEGIN

  SELECT COUNT(*) INTO _count
  FROM pg_stat_activity;
  IF (_count IS NULL) THEN
    _count := 0;
  END IF;

  RETURN _count;

END;

Function: public.openaccountingperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  _r RECORD;

BEGIN

--  Check to make use that the period is closed
  IF ( ( SELECT (NOT period_closed)
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

  IF ( ( SELECT (count(period_id) > 0)
           FROM period
          WHERE ((period_end > (
            SELECT period_end 
            FROM period 
            WHERE (period_id=pPeriodId))
          )
           AND (period_closed)) ) ) THEN
    RETURN -3;
  END IF;
  
--  Make sure the year is open
  IF ( ( SELECT (yearperiod_closed)
         FROM yearperiod
           JOIN period ON (period_yearperiod_id=yearperiod_id)
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -4;
  END IF;

--  Reset the period_closed flag
  UPDATE period
  SET period_closed=FALSE
  WHERE (period_id=pPeriodid);

--  Post any unposted G/L Transactions into the new period
  FOR _r IN SELECT DISTINCT gltrans_sequence
            FROM gltrans, period
            WHERE ( (NOT gltrans_posted)
             AND (gltrans_date BETWEEN period_start AND period_end)
             AND (period_id=pPeriodid) ) LOOP
    PERFORM postIntoTrialBalance(_r.gltrans_sequence);
  END LOOP;

  RETURN pPeriodid;

END;

Function: public.openaccountingyearperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pYearPeriodId ALIAS FOR $1;
  _r RECORD;

BEGIN

--  Check to make use that the yearperiod is closed
  IF ( ( SELECT (NOT yearperiod_closed)
         FROM yearperiod
         WHERE (yearperiod_id=pYearPeriodId) ) ) THEN
    RETURN -1;
  END IF;

  IF ( ( SELECT (count(yearperiod_id) > 0)
           FROM yearperiod
          WHERE ((yearperiod_end> (
            SELECT yearperiod_end 
            FROM yearperiod 
            WHERE (yearperiod_id=pYearPeriodId))
          )
           AND (yearperiod_closed)) ) ) THEN
    RETURN -2;
  END IF;

--  Reset the yearperiod_closed flag
  UPDATE yearperiod
  SET yearperiod_closed=FALSE
  WHERE (yearperiod_id=pYearPeriodId);

  RETURN pYearPeriodid;

END;

Function: public.openapitemsvalue(pperiodid integer, pvendid integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _value NUMERIC;

BEGIN

  SELECT SUM( (apopen_amount - apopen_paid) / apopen_curr_rate *
               CASE WHEN (apopen_doctype IN ('D', 'V')) THEN 1 ELSE -1 END )
               INTO _value
  FROM apopen
  WHERE ( (apopen_open)
    AND   (apopen_vend_id=pVendid)
    AND   (apopen_duedate BETWEEN findPeriodStart(pPeriodid) AND findPeriodEnd(pPeriodid)) );

  RETURN COALESCE(_value, 0.0);

END;

Function: public.openaritemsvalue(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT SUM( CASE WHEN (aropen_doctype IN ('C', 'R')) THEN ((aropen_amount - aropen_paid) * -1)
                   ELSE (aropen_amount - aropen_paid)
              END )  INTO _value
  FROM aropen
  WHERE ( (aropen_open)
    AND (aropen_cust_id=pCustid)
    AND (aropen_duedate BETWEEN findPeriodStart(pPeriodid) AND findPeriodEnd(pPeriodid)) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.openrecurringitems(integer, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentid  ALIAS FOR $1;
  pType      TEXT := UPPER($2);
  pDatetime  TIMESTAMP WITH TIME ZONE := COALESCE($3, CURRENT_TIMESTAMP);

  _count     INTEGER := -1;
  _countstmt TEXT;
  _rt        RECORD;

BEGIN
  IF (pParentid IS NULL) THEN
    RETURN -11;
  END IF;
  
  SELECT * INTO _rt FROM recurtype WHERE (UPPER(recurtype_type)=pType);
  GET DIAGNOSTICS _count = ROW_COUNT;
  IF (_count <= 0) THEN
    RETURN -10;
  END IF;

  _countstmt := 'SELECT COUNT(*) FROM [fulltable]'
             || ' WHERE (NOT ([done])'
             || '    AND ([schedcol]>=''$1'')'
             || '    AND ([table]_recurring_[table]_id=''$2''));';
  _countstmt := REPLACE(_countstmt, '[fulltable]',    _rt.recurtype_table);
  _countstmt := REPLACE(_countstmt, '[table]',
                        REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
  _countstmt := REPLACE(_countstmt, '[done]',     _rt.recurtype_donecheck);
  _countstmt := REPLACE(_countstmt, '[schedcol]', _rt.recurtype_schedcol);

  -- 8.4+: EXECUTE _countstmt INTO _count USING pDatetime, pParentid;
  EXECUTE REPLACE(REPLACE(_countstmt, '$1', pDatetime::TEXT),
                                      '$2', pParentid::TEXT) INTO _count;

  RETURN _count;
END;

Function: public.ophead()

Returns: SET OF ophead

Language: PLPGSQL

A table function that returns Opportunity results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row ophead%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllOpportunities','ViewAllOpportunities','MaintainPersonalOpportunities','ViewPersonalOpportunities')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM ophead
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM ophead 
      WHERE getEffectiveXtUser() IN (ophead_owner_username, ophead_username)
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.orderedbypo(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _qty NUMERIC;

BEGIN

  SELECT COALESCE(SUM(noNeg(poitem_qty_ordered - poitem_qty_received) * poitem_invvenduomratio), 0.0) INTO _qty
  FROM poitem
  WHERE ( (poitem_itemsite_id=pItemsiteid)
    AND (poitem_status <> 'C')
    AND (poitem_duedate BETWEEN pStartDate AND pEndDate) );

  RETURN _qty;

END;

Function: public.orderedbypo(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAhead ALIAS FOR $2;
  _qty NUMERIC;

BEGIN

  SELECT orderedByPo(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookAhead)) INTO _qty;
  RETURN _qty;

END;

Function: public.orderedbywo(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _itemType CHARACTER(1);
  _qty NUMERIC := 0;

BEGIN
  SELECT item_type INTO _itemType
  FROM itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_id=pItemsiteid) );
  
  IF (_itemType NOT IN ('C','T')) THEN
    SELECT COALESCE(SUM(noNeg(wo_qtyord - wo_qtyrcv)), 0.0) INTO _qty
    FROM wo
    WHERE ( (wo_status <> 'C')
     AND (wo_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) );
  ELSIF (_itemType = 'C') THEN
    SELECT COALESCE(SUM((noNeg(wo_qtyord - wo_qtyrcv) * brddist_stdqtyper)), 0.0) INTO _qty
    FROM wo, xtmfg.brddist
    WHERE ( (wo_status <> 'C')
     AND (brddist_wo_id=wo_id)
     AND (brddist_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) );
  ELSIF (_itemType = 'T' AND fetchMetricBool('Routings')) THEN -- Tooling:  Determine quantity already returned
    SELECT
      -- Qty Required
      COALESCE(SUM(noNeg(womatl_qtyreq)),0)  - 
      -- Qty Returned
     (SELECT COALESCE(SUM(abs(invhist_invqty)),0) 
      FROM wo
        JOIN womatl ON (womatl_wo_id=wo_id)
        JOIN womatlpost ON (womatl_id=womatlpost_womatl_id)
        JOIN invhist ON ((womatlpost_invhist_id=invhist_id)
                     AND (invhist_invqty < 0))   
      LEFT OUTER JOIN xtmfg.wooper ON (womatl_wooper_id=wooper_id)
    WHERE ( NOT (COALESCE(wooper_rncomplete,wo_status = 'C'))
     AND (womatl_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) )
       )
   INTO _qty
    FROM wo
      JOIN womatl ON (womatl_wo_id=wo_id)
      LEFT OUTER JOIN xtmfg.wooper ON (womatl_wooper_id=wooper_id)
    WHERE ( NOT (COALESCE(wooper_rncomplete,wo_status = 'C'))
     AND (womatl_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) )
    GROUP BY womatl_qtyreq;   
  ELSIF (_itemType = 'T') THEN -- Tooling:  Determine quantity already returned
    SELECT
      -- Qty Required
      COALESCE(SUM(noNeg(womatl_qtyreq)),0)  - 
      -- Qty Returned
     (SELECT COALESCE(SUM(abs(invhist_invqty)),0) 
      FROM wo
        JOIN womatl ON (womatl_wo_id=wo_id)
        JOIN womatlpost ON (womatl_id=womatlpost_womatl_id)
        JOIN invhist ON ((womatlpost_invhist_id=invhist_id)
                     AND (invhist_invqty < 0))
    WHERE ( NOT (wo_status = 'C')
     AND (womatl_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) )
       )
   INTO _qty
    FROM wo
      JOIN womatl ON (womatl_wo_id=wo_id)
    WHERE ( NOT (wo_status = 'C')
     AND (womatl_itemsite_id=pItemsiteid)
     AND (wo_duedate BETWEEN pStartDate AND pEndDate) )
    GROUP BY womatl_qtyreq;   
  END IF;

  RETURN COALESCE(_qty,0);

END;

Function: public.orderedbywo(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAheadDays ALIAS FOR $2;

BEGIN

  RETURN orderedByWo(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookAheadDays));

END;

Function: public.orderhead()

Returns: SET OF ordhead

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row ordhead%ROWTYPE;
  _query TEXT;
BEGIN

  _query := '
  SELECT DISTINCT * FROM (
  SELECT pohead_id		AS orderhead_id,
	 ''PO''			AS orderhead_type,
	 pohead_number		AS orderhead_number,
	 pohead_status		AS orderhead_status,
	 pohead_orderdate	AS orderhead_orderdate,
	 (SELECT count(*)
	   FROM poitem
	   WHERE poitem_pohead_id=pohead_id) AS orderhead_linecount,
	 pohead_vend_id		AS orderhead_from_id,
	 vend_name		AS orderhead_from,
	 NULL			AS orderhead_to_id,
	 ''''			AS orderhead_to,
	 pohead_curr_id		AS orderhead_curr_id,
	 pohead_agent_username	AS orderhead_agent_username,
	 pohead_shipvia		AS orderhead_shipvia
  FROM pohead LEFT OUTER JOIN vendinfo ON (pohead_vend_id=vend_id)
  UNION
  SELECT cohead_id		AS orderhead_id,
	 ''SO''			AS orderhead_type,
	 cohead_number		AS orderhead_number,
	 COALESCE(coitem_status,''C'') AS orderhead_status,
	 cohead_orderdate	AS orderhead_orderdate,
	 (SELECT count(*)
	   FROM coitem
	   WHERE coitem_cohead_id=cohead_id) AS orderhead_linecount,
	 NULL			AS orderhead_from_id,
	 ''''			AS orderhead_from,
	 cohead_cust_id		AS orderhead_to_id,
	 cust_name		AS orderhead_to,
	 cohead_curr_id		AS orderhead_curr_id,
	 ''''			AS orderhead_agent_username,
	 cohead_shipvia		AS orderhead_shipvia
  FROM cohead LEFT OUTER JOIN custinfo ON (cohead_cust_id=cust_id)
              LEFT OUTER JOIN coitem ON ((cohead_id=coitem_cohead_id)
                                     AND (coitem_status=''O''))';

  IF (fetchmetricbool('MultiWhs')) THEN
    _query := _query || '
    UNION
    SELECT tohead_id		AS orderhead_id,
	 ''TO''			AS orderhead_type,
  	 tohead_number		AS orderhead_number,
	 tohead_status		AS orderhead_status,
	 tohead_orderdate	AS orderhead_orderdate,
	 (SELECT count(*)
	   FROM toitem
	   WHERE toitem_tohead_id=tohead_id) AS orderhead_linecount,
	 tohead_src_warehous_id	 AS orderhead_from_id,
	 tohead_srcname		AS orderhead_from,
	 tohead_dest_warehous_id AS orderhead_to_id,
	 tohead_destname	AS orderhead_to,
	 tohead_freight_curr_id	AS orderhead_curr_id,
	 tohead_agent_username	AS orderhead_agent_username,
	 tohead_shipvia		AS orderhead_shipvia
    FROM tohead';
  END IF;

  IF (fetchmetricbool('EnableReturnAuth')) THEN
    _query := _query || '
  UNION
    SELECT rahead_id		AS orderhead_id,
	 ''RA''			AS orderhead_type,
	 rahead_number		AS orderhead_number,
	 COALESCE(raitem_status,''C'') AS orderhead_status,
	 rahead_authdate	AS orderhead_orderdate,
	 (SELECT count(*)
	   FROM raitem
	   WHERE raitem_rahead_id=rahead_id) AS orderhead_linecount,
	 rahead_cust_id		AS orderhead_from_id,
	 cust_name		AS orderhead_from,
	 NULL			AS orderhead_to_id,
	 ''''			AS orderhead_to,
	 rahead_curr_id		AS orderhead_curr_id,
	 ''''			AS orderhead_agent_username,
	 ''''			AS orderhead_shipvia
    FROM rahead LEFT OUTER JOIN custinfo ON (rahead_cust_id=cust_id)
              LEFT OUTER JOIN raitem ON ((rahead_id=raitem_rahead_id)
                                     AND (raitem_status=''O''))';
  END IF;

  _query := _query || ') AS data ORDER BY orderhead_type, orderhead_number ;';
  
  FOR _row IN EXECUTE _query
  LOOP
    RETURN NEXT _row;
  END LOOP;

  RETURN;
END;

Function: public.orderitem()

Returns: SET OF orditem

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row orditem%ROWTYPE;
  _query TEXT;
BEGIN

  _query := '
  SELECT poitem_id		AS orderitem_id,
	 ''PO''			AS orderitem_orderhead_type,
	 poitem_pohead_id	AS orderitem_orderhead_id,
	 poitem_linenumber	AS orderitem_linenumber,
	 poitem_status		AS orderitem_status,
	 poitem_itemsite_id	AS orderitem_itemsite_id,
	 poitem_duedate		AS orderitem_scheddate,
	 poitem_qty_ordered	AS orderitem_qty_ordered,
	 poitem_qty_returned	AS orderitem_qty_shipped,
	 poitem_qty_received	AS orderitem_qty_received,
	 uom_id			AS orderitem_qty_uom_id,
	 poitem_invvenduomratio	AS orderitem_qty_invuomratio,
	 poitem_unitprice	AS orderitem_unitcost,
	 pohead_curr_id         AS orderitem_unitcost_curr_id,
	 poitem_freight		AS orderitem_freight,
	 poitem_freight_received AS orderitem_freight_received,
	 pohead_curr_id         AS orderitem_freight_curr_id

  FROM poitem LEFT OUTER JOIN pohead ON (poitem_pohead_id=pohead_id)
              LEFT OUTER JOIN uom ON (uom_name=poitem_vend_uom)
  UNION
  SELECT coitem_id		AS orderitem_id,
	 ''SO''			AS orderitem_orderhead_type,
	 coitem_cohead_id	AS orderitem_orderhead_id,
	 coitem_linenumber	AS orderitem_linenumber,
	 coitem_status		AS orderitem_status,
	 coitem_itemsite_id	AS orderitem_itemsite_id,
	 coitem_scheddate	AS orderitem_scheddate,
	 coitem_qtyord		AS orderitem_qty_ordered,
	 coitem_qtyshipped	AS orderitem_qty_shipped,
	 coitem_qtyreturned	AS orderitem_qty_received,
	 coitem_qty_uom_id	AS orderitem_qty_uom_id,
	 coitem_qty_invuomratio	AS orderitem_qty_invuomratio,
	 coitem_unitcost	AS orderitem_unitcost,
	 basecurrid()		AS orderitem_unitcost_curr_id,
	 NULL			AS orderitem_freight,
	 NULL			AS orderitem_freight_received,
	 basecurrid()		AS orderitem_freight_curr_id
  FROM coitem';

  IF (fetchmetricbool('MultiWhs')) THEN
    _query := _query || '
    UNION
    SELECT toitem_id		AS orderitem_id,
      ''TO''			AS orderitem_orderhead_type,
      toitem_tohead_id	AS orderitem_orderhead_id,
      toitem_linenumber	AS orderitem_linenumber,
      toitem_status		AS orderitem_status,
      itemsite_id		AS orderitem_itemsite_id,
      toitem_duedate		AS orderitem_scheddate,
      toitem_qty_ordered	AS orderitem_qty_ordered,
      toitem_qty_shipped	AS orderitem_qty_shipped,
      toitem_qty_received	AS orderitem_qty_received,
      uom_id			AS orderitem_qty_uom_id,
      1			AS orderitem_qty_invuomratio,
      toitem_stdcost		AS orderitem_unitcost,
      basecurrid()		AS orderitem_unitcost_curr_id,
      toitem_freight		AS orderitem_freight,
      toitem_freight_received AS orderitem_freight_received,
      toitem_freight_curr_id	AS orderitem_freight_curr_id
    FROM tohead, itemsite, toitem LEFT OUTER JOIN uom ON (uom_name=toitem_uom)
    WHERE ((toitem_tohead_id=tohead_id)
     AND  (tohead_src_warehous_id=itemsite_warehous_id)
     AND  (toitem_item_id=itemsite_item_id)) ';
  END IF;

  IF (fetchmetricbool('EnableReturnAuth')) THEN
    _query := _query || '
    UNION
    SELECT raitem_id		AS orderitem_id,
      ''RA''			AS orderitem_orderhead_type,
      raitem_rahead_id	AS orderitem_orderhead_id,
      raitem_linenumber	AS orderitem_linenumber,
      raitem_status		AS orderitem_status,
      raitem_itemsite_id	AS orderitem_itemsite_id,
      raitem_scheddate	AS orderitem_scheddate,
      raitem_qtyauthorized	AS orderitem_qty_ordered,
      0			AS orderitem_qty_shipped,
      raitem_qtyreceived	AS orderitem_qty_received,
      raitem_qty_uom_id	AS orderitem_qty_uom_id,
      raitem_qty_invuomratio	AS orderitem_qty_invuomratio,
      raitem_unitprice	AS orderitem_unitcost,
      basecurrid()		AS orderitem_unitcost_curr_id,
      NULL			AS orderitem_freight,
      NULL			AS orderitem_freight_received,
      basecurrid()		AS orderitem_freight_curr_id
    FROM raitem';
  END IF;
  
  FOR _row IN EXECUTE _query
  LOOP
    RETURN NEXT _row;
  END LOOP;

  RETURN;
END;

Function: public.orderitemdata(text, integer, integer)

Returns: SET OF orderitemtype

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pOrdertype ALIAS FOR $1;
  pOrderheadid ALIAS FOR $2;
  pOrderitemid ALIAS FOR $3;
  _row orderitemtype%ROWTYPE;
  _set RECORD;

BEGIN

  IF(UPPER(pOrdertype)='PO') THEN
    FOR _set IN 
      SELECT poitem_id              AS orderitem_id,
             'PO'                   AS orderitem_orderhead_type,
             poitem_pohead_id       AS orderitem_orderhead_id,
             poitem_linenumber      AS orderitem_linenumber,
             poitem_status          AS orderitem_status,
             poitem_itemsite_id     AS orderitem_itemsite_id,
             poitem_duedate         AS orderitem_scheddate,
             poitem_qty_ordered     AS orderitem_qty_ordered,
             poitem_qty_returned    AS orderitem_qty_shipped,
             poitem_qty_received    AS orderitem_qty_received,
             uom_id                 AS orderitem_qty_uom_id,
             poitem_invvenduomratio AS orderitem_qty_invuomratio,
             poitem_unitprice       AS orderitem_unitcost,
             (SELECT pohead_curr_id FROM pohead WHERE pohead_id=poitem_pohead_id)
                                    AS orderitem_unitcost_curr_id,
             poitem_freight         AS orderitem_freight,
             poitem_freight_received AS orderitem_freight_received,
             (SELECT pohead_curr_id FROM pohead WHERE pohead_id=poitem_pohead_id)
                                    AS orderitem_freight_curr_id
        FROM poitem LEFT OUTER JOIN uom ON (uom_name=poitem_vend_uom)
       WHERE(((pOrderheadid IS NULL) OR (poitem_pohead_id=pOrderheadid))
         AND ((pOrderitemid IS NULL) OR (poitem_id=pOrderitemid))) LOOP
  
      _row.orderitem_id := _set.orderitem_id;
      _row.orderitem_orderhead_type := _set.orderitem_orderhead_type;
      _row.orderitem_orderhead_id := _set.orderitem_orderhead_id;
      _row.orderitem_linenumber := _set.orderitem_linenumber;
      _row.orderitem_status := _set.orderitem_status;
      _row.orderitem_itemsite_id := _set.orderitem_itemsite_id;
      _row.orderitem_scheddate := _set.orderitem_scheddate;
      _row.orderitem_qty_ordered := _set.orderitem_qty_ordered;
      _row.orderitem_qty_shipped := _set.orderitem_qty_shipped;
      _row.orderitem_qty_received := _set.orderitem_qty_received;
      _row.orderitem_qty_uom_id := _set.orderitem_qty_uom_id;
      _row.orderitem_qty_invuomratio := _set.orderitem_qty_invuomratio;
      _row.orderitem_unitcost := _set.orderitem_unitcost;
      _row.orderitem_unitcost_curr_id := _set.orderitem_unitcost_curr_id;
      _row.orderitem_freight := _set.orderitem_freight;
      _row.orderitem_freight_received := _set.orderitem_freight_received;
      _row.orderitem_freight_curr_id := _set.orderitem_freight_curr_id;

      RETURN NEXT _row;
    END LOOP;
  ELSEIF(UPPER(pOrdertype)='SO') THEN
    FOR _set IN 
      SELECT coitem_id              AS orderitem_id,
             'SO'                   AS orderitem_orderhead_type,
             coitem_cohead_id       AS orderitem_orderhead_id,
             coitem_linenumber      AS orderitem_linenumber,
             coitem_status          AS orderitem_status,
             coitem_itemsite_id     AS orderitem_itemsite_id,
             coitem_scheddate       AS orderitem_scheddate,
             coitem_qtyord          AS orderitem_qty_ordered,
             coitem_qtyshipped      AS orderitem_qty_shipped,
             coitem_qtyreturned     AS orderitem_qty_received,
             coitem_qty_uom_id      AS orderitem_qty_uom_id,
             coitem_qty_invuomratio AS orderitem_qty_invuomratio,
             coitem_unitcost        AS orderitem_unitcost,
             basecurrid()           AS orderitem_unitcost_curr_id,
             NULL                   AS orderitem_freight,
             NULL                   AS orderitem_freight_received,
             basecurrid()           AS orderitem_freight_curr_id
        FROM coitem
       WHERE(((pOrderheadid IS NULL) OR (coitem_cohead_id=pOrderheadid))
         AND ((pOrderitemid IS NULL) OR (coitem_id=pOrderitemid))) LOOP
  
      _row.orderitem_id := _set.orderitem_id;
      _row.orderitem_orderhead_type := _set.orderitem_orderhead_type;
      _row.orderitem_orderhead_id := _set.orderitem_orderhead_id;
      _row.orderitem_linenumber := _set.orderitem_linenumber;
      _row.orderitem_status := _set.orderitem_status;
      _row.orderitem_itemsite_id := _set.orderitem_itemsite_id;
      _row.orderitem_scheddate := _set.orderitem_scheddate;
      _row.orderitem_qty_ordered := _set.orderitem_qty_ordered;
      _row.orderitem_qty_shipped := _set.orderitem_qty_shipped;
      _row.orderitem_qty_received := _set.orderitem_qty_received;
      _row.orderitem_qty_uom_id := _set.orderitem_qty_uom_id;
      _row.orderitem_qty_invuomratio := _set.orderitem_qty_invuomratio;
      _row.orderitem_unitcost := _set.orderitem_unitcost;
      _row.orderitem_unitcost_curr_id := _set.orderitem_unitcost_curr_id;
      _row.orderitem_freight := _set.orderitem_freight;
      _row.orderitem_freight_received := _set.orderitem_freight_received;
      _row.orderitem_freight_curr_id := _set.orderitem_freight_curr_id;

      RETURN NEXT _row;
    END LOOP;
  ELSEIF(UPPER(pOrdertype)='RA') THEN
    FOR _set IN 
      SELECT raitem_id              AS orderitem_id,
             'RA'                   AS orderitem_orderhead_type,
             raitem_rahead_id       AS orderitem_orderhead_id,
             raitem_linenumber      AS orderitem_linenumber,
             raitem_status          AS orderitem_status,
             raitem_itemsite_id     AS orderitem_itemsite_id,
             raitem_scheddate       AS orderitem_scheddate,
             raitem_qtyauthorized   AS orderitem_qty_ordered,
             0                      AS orderitem_qty_shipped,
             raitem_qtyreceived     AS orderitem_qty_received,
             raitem_qty_uom_id      AS orderitem_qty_uom_id,
             raitem_qty_invuomratio AS orderitem_qty_invuomratio,
             raitem_unitprice       AS orderitem_unitcost,
             basecurrid()           AS orderitem_unitcost_curr_id,
             NULL                   AS orderitem_freight,
             NULL                   AS orderitem_freight_received,
             basecurrid()           AS orderitem_freight_curr_id
        FROM raitem
       WHERE(((pOrderheadid IS NULL) OR (raitem_rahead_id=pOrderheadid))
         AND ((pOrderitemid IS NULL) OR (raitem_id=pOrderitemid))) LOOP
  
      _row.orderitem_id := _set.orderitem_id;
      _row.orderitem_orderhead_type := _set.orderitem_orderhead_type;
      _row.orderitem_orderhead_id := _set.orderitem_orderhead_id;
      _row.orderitem_linenumber := _set.orderitem_linenumber;
      _row.orderitem_status := _set.orderitem_status;
      _row.orderitem_itemsite_id := _set.orderitem_itemsite_id;
      _row.orderitem_scheddate := _set.orderitem_scheddate;
      _row.orderitem_qty_ordered := _set.orderitem_qty_ordered;
      _row.orderitem_qty_shipped := _set.orderitem_qty_shipped;
      _row.orderitem_qty_received := _set.orderitem_qty_received;
      _row.orderitem_qty_uom_id := _set.orderitem_qty_uom_id;
      _row.orderitem_qty_invuomratio := _set.orderitem_qty_invuomratio;
      _row.orderitem_unitcost := _set.orderitem_unitcost;
      _row.orderitem_unitcost_curr_id := _set.orderitem_unitcost_curr_id;
      _row.orderitem_freight := _set.orderitem_freight;
      _row.orderitem_freight_received := _set.orderitem_freight_received;
      _row.orderitem_freight_curr_id := _set.orderitem_freight_curr_id;

      RETURN NEXT _row;
    END LOOP;
  ELSEIF(UPPER(pOrdertype)='TO') THEN
    FOR _set IN 
      SELECT toitem_id              AS orderitem_id,
             'TO'                   AS orderitem_orderhead_type,
             toitem_tohead_id       AS orderitem_orderhead_id,
             toitem_linenumber      AS orderitem_linenumber,
             toitem_status          AS orderitem_status,
             itemsite_id            AS orderitem_itemsite_id,
             toitem_duedate         AS orderitem_scheddate,
             toitem_qty_ordered     AS orderitem_qty_ordered,
             toitem_qty_shipped     AS orderitem_qty_shipped,
             toitem_qty_received    AS orderitem_qty_received,
             uom_id                 AS orderitem_qty_uom_id,
             1                      AS orderitem_qty_invuomratio,
             toitem_stdcost         AS orderitem_unitcost,
             basecurrid()           AS orderitem_unitcost_curr_id,
             toitem_freight         AS orderitem_freight,
             toitem_freight_received AS orderitem_freight_received,
             toitem_freight_curr_id AS orderitem_freight_curr_id
        FROM tohead, itemsite, toitem LEFT OUTER JOIN uom ON (uom_name=toitem_uom)
       WHERE((toitem_tohead_id=tohead_id)
         AND (tohead_src_warehous_id=itemsite_warehous_id)
         AND (toitem_item_id=itemsite_item_id)
         AND ((pOrderheadid IS NULL) OR (toitem_tohead_id=pOrderheadid))
         AND ((pOrderitemid IS NULL) OR (toitem_id=pOrderitemid))) LOOP
  
      _row.orderitem_id := _set.orderitem_id;
      _row.orderitem_orderhead_type := _set.orderitem_orderhead_type;
      _row.orderitem_orderhead_id := _set.orderitem_orderhead_id;
      _row.orderitem_linenumber := _set.orderitem_linenumber;
      _row.orderitem_status := _set.orderitem_status;
      _row.orderitem_itemsite_id := _set.orderitem_itemsite_id;
      _row.orderitem_scheddate := _set.orderitem_scheddate;
      _row.orderitem_qty_ordered := _set.orderitem_qty_ordered;
      _row.orderitem_qty_shipped := _set.orderitem_qty_shipped;
      _row.orderitem_qty_received := _set.orderitem_qty_received;
      _row.orderitem_qty_uom_id := _set.orderitem_qty_uom_id;
      _row.orderitem_qty_invuomratio := _set.orderitem_qty_invuomratio;
      _row.orderitem_unitcost := _set.orderitem_unitcost;
      _row.orderitem_unitcost_curr_id := _set.orderitem_unitcost_curr_id;
      _row.orderitem_freight := _set.orderitem_freight;
      _row.orderitem_freight_received := _set.orderitem_freight_received;
      _row.orderitem_freight_curr_id := _set.orderitem_freight_curr_id;

      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;
END;

Function: public.packageisenabled(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT COUNT(*) >= 8
  FROM pg_inherits, pg_class, pg_namespace, pkghead
  WHERE ((inhrelid=pg_class.oid)
     AND (relnamespace=pg_namespace.oid)
     AND  (nspname=lower(pkghead_name))
     AND  (pkghead_id=$1));

Function: public.packageisenabled(text)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT COUNT(*) >= 8
  FROM pg_inherits, pg_class, pg_namespace
  WHERE ((inhrelid=pg_class.oid)
     AND (relnamespace=pg_namespace.oid)
     AND  (nspname=lower($1)));

Function: public.pgp_key_id(bytea)

Returns: text

Language: C

pgp_key_id_w

Function: public.pgp_pub_decrypt(bytea, bytea)

Returns: text

Language: C

pgp_pub_decrypt_text

Function: public.pgp_pub_decrypt(bytea, bytea, text)

Returns: text

Language: C

pgp_pub_decrypt_text

Function: public.pgp_pub_decrypt(bytea, bytea, text, text)

Returns: text

Language: C

pgp_pub_decrypt_text

Function: public.pgp_pub_decrypt_bytea(bytea, bytea)

Returns: bytea

Language: C

pgp_pub_decrypt_bytea

Function: public.pgp_pub_decrypt_bytea(bytea, bytea, text)

Returns: bytea

Language: C

pgp_pub_decrypt_bytea

Function: public.pgp_pub_decrypt_bytea(bytea, bytea, text, text)

Returns: bytea

Language: C

pgp_pub_decrypt_bytea

Function: public.pgp_pub_encrypt(text, bytea)

Returns: bytea

Language: C

pgp_pub_encrypt_text

Function: public.pgp_pub_encrypt(text, bytea, text)

Returns: bytea

Language: C

pgp_pub_encrypt_text

Function: public.pgp_pub_encrypt_bytea(bytea, bytea)

Returns: bytea

Language: C

pgp_pub_encrypt_bytea

Function: public.pgp_pub_encrypt_bytea(bytea, bytea, text)

Returns: bytea

Language: C

pgp_pub_encrypt_bytea

Function: public.pgp_sym_decrypt(bytea, text)

Returns: text

Language: C

pgp_sym_decrypt_text

Function: public.pgp_sym_decrypt(bytea, text, text)

Returns: text

Language: C

pgp_sym_decrypt_text

Function: public.pgp_sym_decrypt_bytea(bytea, text)

Returns: bytea

Language: C

pgp_sym_decrypt_bytea

Function: public.pgp_sym_decrypt_bytea(bytea, text, text)

Returns: bytea

Language: C

pgp_sym_decrypt_bytea

Function: public.pgp_sym_encrypt(text, text)

Returns: bytea

Language: C

pgp_sym_encrypt_text

Function: public.pgp_sym_encrypt(text, text, text)

Returns: bytea

Language: C

pgp_sym_encrypt_text

Function: public.pgp_sym_encrypt_bytea(bytea, text)

Returns: bytea

Language: C

pgp_sym_encrypt_bytea

Function: public.pgp_sym_encrypt_bytea(bytea, text, text)

Returns: bytea

Language: C

pgp_sym_encrypt_bytea

Function: public.pkgmaybemodified(name)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pschemaname ALIAS FOR $1;
  _returnval  BOOLEAN;
BEGIN
  SELECT pkghead_indev INTO _returnval
  FROM pkghead
  WHERE (pkghead_name=pschemaname);
  IF (NOT FOUND) THEN
    RETURN FALSE;
  END IF;
  RETURN _returnval;
END;

Function: public.plpgsql_validator(oid)

Returns: void

Language: C

plpgsql_validator

Function: public.postapcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postAPCheck() is deprecated - use postCheck() instead';
  RETURN postCheck($1, fetchJournalNumber('AP-CK'));
END;

Function: public.postapcheck(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postAPCheck() is deprecated - use postCheck() instead';
  RETURN postCheck($1, $2);
END;

Function: public.postapchecks(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  RAISE NOTICE 'postAPChecks() is deprecated - use postChecks() instead';
  RETURN postChecks($1);

END;

Function: public.postapcreditmemoapplication(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  _src RECORD;
  _r RECORD;
  _totalAmount NUMERIC := 0;
  _exchGain NUMERIC;
  _apaccntid INTEGER;

BEGIN

  SELECT apopen_docnumber, (apopen_amount - apopen_paid) AS balance,
         SUM(currtocurr(apcreditapply_curr_id, apopen_curr_id,
				 apcreditapply_amount, CURRENT_DATE)) AS toApply,
	 SUM(apcreditapply_amount) AS junk,
	 apopen_curr_rate INTO _src
  FROM apopen, apcreditapply
  WHERE ( (apcreditapply_source_apopen_id=apopen_id)
   AND (apopen_id=pApopenid) )
  GROUP BY apopen_docnumber, apopen_amount, apopen_paid,
	   apopen_curr_rate;
  IF (NOT FOUND) THEN
    RETURN -1;
  ELSIF (_src.toApply = 0) THEN
    RETURN -2;
  ELSIF (_src.toApply > _src.balance) THEN
    RETURN -3;
  ELSIF (_src.toApply IS NULL AND _src.junk IS NOT NULL) THEN
    RETURN -4;		-- missing exchange rate
  ELSIF (_src.toApply IS NULL) THEN
    RETURN -6;		-- amount to apply is NULL for some unknown reason
  END IF;

  SELECT apopen_id, apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_amount,
         apopen_curr_id, apopen_curr_rate, apopen_docdate, apopen_accnt_id INTO _src
  FROM apopen
  WHERE (apopen_id=pApopenid);
  IF (NOT FOUND) THEN
    RETURN -5;
  END IF;

  FOR _r IN SELECT apcreditapply_id, apcreditapply_target_apopen_id,
		   apcreditapply_amount AS apply_amountSource,
                   currToCurr(apcreditapply_curr_id, apopen_curr_id,
                              apcreditapply_amount, CURRENT_DATE) AS apply_amountTarget,
                   apopen_id, apopen_doctype, apopen_docnumber, apopen_curr_rate, apopen_docdate
            FROM apcreditapply, apopen
            WHERE ( (apcreditapply_source_apopen_id=pApopenid)
             AND (apcreditapply_target_apopen_id=apopen_id) ) LOOP

    IF (_r.apply_amountTarget IS NULL) THEN
      RETURN -4;	-- missing exchange rate
    END IF;

    IF (_r.apply_amountTarget > 0) THEN

--  Update the apopen item to post the paid amount
      UPDATE apopen
      SET apopen_paid = (apopen_paid + _r.apply_amountTarget)
      WHERE (apopen_id=_r.apcreditapply_target_apopen_id);

      UPDATE apopen
      SET apopen_open = false,
        apopen_closedate = current_date
      WHERE ( (apopen_id=_r.apcreditapply_target_apopen_id)
        AND (apopen_amount <= apopen_paid) );

--  Cache the running amount posted
      _totalAmount := (_totalAmount + _r.apply_amountSource);

--  Record the application
      INSERT INTO apapply
      ( apapply_vend_id, apapply_amount,
        apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
        apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
        apapply_postdate, apapply_journalnumber, apapply_username, apapply_curr_id )
      VALUES
      ( _src.apopen_vend_id, round(_r.apply_amountSource, 2),
        pApopenid, 'C', _src.apopen_docnumber,
        _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
        CURRENT_DATE, 0, getEffectiveXtUser(), _src.apopen_curr_id );

    END IF;

--  Delete the posted apcreditapply record
    DELETE FROM apcreditapply
    WHERE (apcreditapply_id=_r.apcreditapply_id);

  END LOOP;

--  Record the amount posted and mark the source apopen as closed if it is completely posted
  UPDATE apopen
  SET apopen_paid = (apopen_paid + _totalAmount)
  WHERE (apopen_id=pApopenid);

  UPDATE apopen
  SET apopen_open = false,
    apopen_closedate = current_date
  WHERE ( (apopen_id=pApopenid)
    AND (apopen_amount <= apopen_paid) );

  IF (_r.apopen_docdate > _src.apopen_docdate) THEN
    _exchGain := (_totalAmount / _r.apopen_curr_rate - _totalAmount / _src.apopen_curr_rate) * -1;
  ELSE
    _exchGain := _totalAmount / _src.apopen_curr_rate - _totalAmount / _r.apopen_curr_rate;
  END IF;

  IF (_src.apopen_accnt_id > -1) THEN
    _apaccntid := _src.apopen_accnt_id;
  ELSE 
    _apaccntid := findAPAccount(_src.apopen_vend_id);
  END IF;

  PERFORM insertGLTransaction(fetchJournalNumber('AP-MISC'), 'A/P', 'CM',
                            _src.apopen_docnumber, 'CM Application',
                            _apaccntid,
			    getGainLossAccntId(_apaccntid), -1,
                            _exchGain,
                            CURRENT_DATE);


  RETURN pApopenid;

END;

Function: public.postapopenitems()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  UPDATE apopen
  SET apopen_posted=TRUE
  WHERE (NOT apopen_posted);

  RETURN TRUE;

END;

Function: public.postarcreditmemoapplication(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAropenid ALIAS FOR $1;
BEGIN
  RETURN postARCreditMemoApplication(pAropenid, CURRENT_DATE);
END;

Function: public.postarcreditmemoapplication(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAropenid ALIAS FOR $1;
  _applyDate DATE := COALESCE($2, CURRENT_DATE);
  _p RECORD;
  _r RECORD;
  _totalAmount NUMERIC := 0;
  _totalTarget NUMERIC := 0;
  _exchGain NUMERIC := 0;
  _result NUMERIC;
  _araccntid INTEGER;

BEGIN

  SELECT aropen_docnumber,
         ROUND(aropen_amount - aropen_paid, 2) AS balance,
         aropen_open, aropen_curr_rate,
         ROUND(SUM(currToCurr(arcreditapply_curr_id, aropen_curr_id,
              COALESCE(arcreditapply_amount, 0), _applyDate)), 2) AS toApply INTO _p
  FROM aropen, arcreditapply
  WHERE ( (arcreditapply_source_aropen_id=aropen_id)
   AND (aropen_id=pAropenid) )
  GROUP BY aropen_docnumber, aropen_amount, aropen_paid, aropen_open, aropen_curr_rate;
  IF (NOT FOUND) THEN
    RETURN -1;
  ELSIF (_p.toApply = 0) THEN
    RETURN -2;
  ELSIF (_p.toApply > _p.balance) THEN
    RETURN -3;
  END IF;

  SELECT aropen_cust_id, aropen_docnumber, aropen_doctype, aropen_amount,
         aropen_curr_id, aropen_docdate, aropen_accnt_id, aropen_cust_id,
         aropen_curr_rate INTO _p
  FROM aropen
  WHERE (aropen_id=pAropenid);
  IF (NOT FOUND) THEN
    RETURN -5;
  END IF;

  FOR _r IN SELECT arcreditapply_id, arcreditapply_target_aropen_id,
                   arcreditapply_amount AS arcreditapply_amountSource,
                   arcreditapply_reftype, arcreditapply_ref_id,
                   currToCurr(arcreditapply_curr_id, aropen_curr_id,
                              arcreditapply_amount, _applyDate) AS arcreditapply_amountTarget,
                   aropen_id, aropen_doctype, aropen_docnumber, aropen_docdate, aropen_curr_rate
            FROM arcreditapply, aropen
            WHERE ( (arcreditapply_source_aropen_id=pAropenid)
             AND (arcreditapply_target_aropen_id=aropen_id) ) LOOP

    IF (_r.arcreditapply_amountTarget IS NULL) THEN
      RETURN -4;
    END IF;

    IF (_r.arcreditapply_amountTarget > 0) THEN

--  Update the aropen item to post the paid amount
      UPDATE aropen
      SET aropen_paid = round(aropen_paid + _r.arcreditapply_amountTarget, 2)
      WHERE (aropen_id=_r.arcreditapply_target_aropen_id);

      UPDATE aropen
      SET aropen_open = (round(aropen_amount, 2) > round(aropen_paid, 2))
      WHERE (aropen_id=_r.arcreditapply_target_aropen_id);

--  Cache the running amount posted
      _totalAmount := (_totalAmount + _r.arcreditapply_amountSource);
      _totalTarget := (_totalTarget + _r.arcreditapply_amountTarget);

--  Record the application
      INSERT INTO arapply
      ( arapply_cust_id,
        arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
        arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
        arapply_fundstype, arapply_refnumber,
        arapply_applied, arapply_closed, arapply_postdate, arapply_distdate,
        arapply_journalnumber, arapply_username, arapply_curr_id,
        arapply_reftype, arapply_ref_id )
      VALUES
      ( _p.aropen_cust_id,
        pAropenid, _p.aropen_doctype, _p.aropen_docnumber,
        _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
        '', '',
        round(_r.arcreditapply_amountSource, 2), TRUE, _applyDate, _applyDate,
        0, getEffectiveXtUser(), _p.aropen_curr_id, 
        _r.arcreditapply_reftype, _r.arcreditapply_ref_id );

    END IF;

--  Delete the posted arcreditapply record
    DELETE FROM arcreditapply
    WHERE (arcreditapply_id=_r.arcreditapply_id);

    IF (_r.aropen_docdate > _p.aropen_docdate) THEN
      _exchGain := (_totalTarget / _r.aropen_curr_rate - _totalAmount / _p.aropen_curr_rate) * -1;
    ELSE
      _exchGain := _totalAmount / _p.aropen_curr_rate - _totalTarget / _r.aropen_curr_rate;
    END IF;

    IF (_p.aropen_accnt_id > -1) THEN
      _araccntid := _p.aropen_accnt_id;
    ELSE 
      _araccntid := findARAccount(_p.aropen_cust_id);
    END IF;
    
    IF (_exchGain <> 0) THEN
        PERFORM insertGLTransaction(fetchJournalNumber('AR-MISC'), 'A/R',
                                    'CR', _p.aropen_docnumber, 'CM Application',
                                    _araccntid, getGainLossAccntId(_araccntid),
                                    -1, _exchGain * -1, _applyDate);
    END IF;

  END LOOP;

-- TODO: If this is a Customer Deposit (aropen_doctype='R')
--       the we need to convert the total to a base transaction
  IF(_p.aropen_doctype='R') THEN
    SELECT insertGLTransaction(fetchJournalNumber('AR-MISC'), 'A/R',
                               'CD', _p.aropen_docnumber, 'CM Application',
                               cr.accnt_id, db.accnt_id,
                               -1, currToBase(_p.aropen_curr_id, _totalAmount, _p.aropen_docdate),
                               _applyDate)
      INTO _result
      FROM accnt AS cr, accnt AS db
     WHERE ((db.accnt_id = findDeferredAccount(_p.aropen_cust_id))
       AND  (cr.accnt_id = findARAccount(_p.aropen_cust_id)) );
    IF(NOT FOUND OR _result < 0) THEN
      RAISE EXCEPTION 'There was an error posting the Customer Deposit GL Transactions.';
    END IF;
  END IF;

--  Record the amount posted and mark the source aropen as closed if it is completely posted
  UPDATE aropen
  SET aropen_paid = round(aropen_paid + _totalAmount, 2)
  WHERE (aropen_id=pAropenid);

  UPDATE aropen
  SET aropen_open = (round(aropen_amount, 2) > round(aropen_paid, 2))
  WHERE (aropen_id=pAropenid);

  RETURN pAropenid;

END;

Function: public.postaropenitems()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  UPDATE aropen
  SET aropen_posted=TRUE
  WHERE (NOT aropen_posted);

  RETURN TRUE;

END;

Function: public.postbankadjustment(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankadjid ALIAS FOR $1;
  _sequence INTEGER;
  _r RECORD;

BEGIN

--  Post the G/L transaction
  SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'), 'G/L', 'AD',
                              bankadj_docnumber, (bankadjtype_name || '-' || bankadj_notes),
                              bankadjtype_accnt_id, bankaccnt_accnt_id, bankadj_id,
                              round(currToBase(bankaccnt_curr_id,
                                         CASE WHEN(bankadjtype_iscredit) THEN
                                             (bankadj_amount * -1)
                                         ELSE bankadj_amount END,
                                         bankadj_date), 2),
                              bankadj_date, TRUE, TRUE ) INTO _sequence
    FROM bankadj, bankaccnt, bankadjtype
   WHERE ( (bankadj_bankaccnt_id=bankaccnt_id)
     AND   (bankadj_bankadjtype_id=bankadjtype_id)
     AND   (NOT bankadj_posted)
     AND   (bankadj_id=pBankadjid) );
  IF ( NOT FOUND ) THEN
    RETURN -1;
  END IF;

  IF (_sequence >= 0) THEN
--  Update the bankadj record with this sequence and mark it posted
    UPDATE bankadj
       SET bankadj_sequence = _sequence,
           bankadj_posted = TRUE
     WHERE bankadj_id=pBankadjid;
  END IF;

  RETURN _sequence;

END;

Function: public.postbankreconciliation(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankrecid ALIAS FOR $1;
  _accntid INTEGER;
  _sequence INTEGER;
  _gltransid INTEGER;
  _r RECORD;

BEGIN

-- Check the accnt information to make sure it is valid
  SELECT accnt_id INTO _accntid
    FROM bankrec, bankaccnt, accnt
   WHERE ( (bankaccnt_accnt_id=accnt_id)
     AND   (bankrec_bankaccnt_id=bankaccnt_id)
     AND   (bankrec_id=pBankrecid) );
  IF ( NOT FOUND ) THEN
    RETURN -1;
  END IF;

-- Delete any bankrecitem records that are not marked as cleared for cleanliness
  DELETE FROM bankrecitem
   WHERE ( (NOT bankrecitem_cleared)
     AND   (bankrecitem_bankrec_id=pBankrecid) );

-- Post any bankadj items that were marked as cleared and convert the bankrecitem
  FOR _r IN SELECT bankrecitem_id, bankrecitem_source_id
              FROM bankrecitem, bankadj
             WHERE ( (bankrecitem_source = 'AD')
               AND   (bankrecitem_source_id=bankadj_id)
               AND   (bankrecitem_cleared)
               AND   (NOT bankadj_posted)
               AND   (bankrecitem_bankrec_id=pBankrecid) ) LOOP

    SELECT postBankAdjustment(_r.bankrecitem_source_id) INTO _sequence;

    IF (_sequence < 0) THEN
      RETURN -10;
    END IF;

    SELECT gltrans_id INTO _gltransid
      FROM gltrans
     WHERE ( (gltrans_sequence=_sequence)
       AND   (gltrans_accnt_id=_accntid) );
    IF ( NOT FOUND ) THEN
      RETURN -11;
    END IF;

    UPDATE bankrecitem
       SET bankrecitem_source = 'GL',
           bankrecitem_source_id=_gltransid
     WHERE (bankrecitem_id=_r.bankrecitem_id);

  END LOOP;

-- Mark all the gltrans items that have been cleared as reconciled.
  UPDATE gltrans
     SET gltrans_rec = TRUE
   WHERE ( (gltrans_id IN (SELECT bankrecitem_source_id
                             FROM bankrecitem
                            WHERE ((bankrecitem_source = 'GL')
                              AND  (bankrecitem_cleared)
                              AND  (bankrecitem_bankrec_id=pBankrecid) ) ) )
     AND   (gltrans_accnt_id=_accntid) ) ;

-- Mark all the sltrans items that have been cleared as reconciled.
  UPDATE sltrans
     SET sltrans_rec = TRUE
   WHERE ( (sltrans_id IN (SELECT bankrecitem_source_id
                             FROM bankrecitem
                            WHERE ((bankrecitem_source = 'SL')
                              AND  (bankrecitem_cleared)
                              AND  (bankrecitem_bankrec_id=pBankrecid) ) ) )
     AND   (sltrans_accnt_id=_accntid) ) ;

-- Mark the bankrec record as posted
  UPDATE bankrec SET 
    bankrec_posted = TRUE,
    bankrec_postdate = now()
   WHERE (bankrec_id=pBankrecid);

  RETURN pBankrecid;
END;

Function: public.postbillingselection(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;

BEGIN

  RAISE NOTICE 'postBillingselection(integer) has been deprecated.  Please use createInvoice(integer).';
  RETURN createInvoice(pCobmiscid);

END;

Function: public.postbillingselectionconsolidated(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustid ALIAS FOR $1;

BEGIN

  RAISE NOTICE 'postBillingselectionConsolidated(integer) has been deprecated.  Please use createInvoiceConsolidated(integer).';
  RETURN createInvoiceConsolidated(pCustid);

END;

Function: public.postbillingselections()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  RAISE NOTICE 'postBillingselections() has been deprecated.  Please use createInvoices().';
  RETURN createInvoices();
  
END;

Function: public.postbillingselections(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postBillingselections(int) has been deprecated.  Please use createInvoices(int).';
  RETURN createInvoices($1, false);
END;

Function: public.postbillingselections(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCustTypeId ALIAS FOR $1;
  pConsolidate ALIAS FOR $2;

BEGIN

  RAISE NOTICE 'postBillingselections(int,bool) has been deprecated.  Please use createInvoices(int,bool).';
  RETURN createInvoices(pCustTypeId, pConsolidate);
  
END;

Function: public.postcashreceipt(pjournalnumber integer, pcashrcptid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _ccpayid  INTEGER;
  _cctype TEXT;
  _p RECORD;
  _r RECORD;
  _t RECORD;
  _v RECORD;
  _postToAR NUMERIC;
  _postToMisc NUMERIC;
  _postToCM NUMERIC;
  _posted_base NUMERIC := 0;
  _posted NUMERIC := 0;
  _sequence INTEGER;
  _aropenid INTEGER;
  _arMemoNumber TEXT;
  _arAccntid INTEGER;
  _closed BOOLEAN;
  _debitAccntid INTEGER;
  _exchGain NUMERIC;
  _comment TEXT;
  _predist BOOLEAN;
  _check INTEGER;

BEGIN
  _posted := 0;
  _posted_base := 0;

  SELECT fetchGLSequence() INTO _sequence;

  SELECT accnt_id INTO _arAccntid
  FROM cashrcpt, accnt, salescat
  WHERE ((cashrcpt_salescat_id=salescat_id)
    AND  (salescat_ar_accnt_id=accnt_id)
    AND  (cashrcpt_id=pCashrcptid));
  IF (NOT FOUND) THEN
    SELECT accnt_id INTO _arAccntid
    FROM cashrcpt LEFT OUTER JOIN accnt ON (accnt_id=findARAccount(cashrcpt_cust_id))
    WHERE ( (findARAccount(cashrcpt_cust_id)=0 OR accnt_id > 0) -- G/L interface might be disabled
     AND (cashrcpt_id=pCashrcptid) );
    IF (NOT FOUND) THEN
      RETURN -5;
    END IF;
  END IF;

  SELECT cashrcpt_cust_id, (cust_number||'-'||cust_name) AS custnote,
         cashrcpt_fundstype, cashrcpt_number, cashrcpt_docnumber,
         cashrcpt_distdate, cashrcpt_amount, cashrcpt_discount,
         (cashrcpt_amount / cashrcpt_curr_rate) AS cashrcpt_amount_base,
	 (cashrcpt_discount / cashrcpt_curr_rate) AS cashrcpt_discount_base,
         cashrcpt_notes,
         cashrcpt_bankaccnt_id AS bankaccnt_id,
         accnt_id AS prepaid_accnt_id,
         cashrcpt_usecustdeposit,
         COALESCE(cashrcpt_applydate, cashrcpt_distdate) AS applydate,
         cashrcpt_curr_id, cashrcpt_curr_rate, cashrcpt_posted, cashrcpt_void INTO _p
  FROM cashrcpt LEFT OUTER JOIN custinfo ON (cashrcpt_cust_id=cust_id)
                LEFT OUTER JOIN accnt ON (accnt_id=findPrepaidAccount(cashrcpt_cust_id))
  WHERE ( (findPrepaidAccount(cashrcpt_cust_id)=0 OR accnt_id > 0) -- G/L interface might be disabled
     AND (cashrcpt_id=pCashrcptid) );
  IF (NOT FOUND) THEN
    RETURN -7;
  END IF;

  IF (COALESCE(_p.cashrcpt_distdate > _p.applydate, false)) THEN
    RAISE EXCEPTION 'Cannot post cashrcpt % because application date is before distribution date.', _p.cashrcpt_docnumber;
  END IF;

  IF (COALESCE(_p.cashrcpt_posted, false)) THEN
    RAISE EXCEPTION 'Cannot post cashrcpt % because the document has already been posted.', _p.cashrcpt_docnumber;
  END IF;

  IF (COALESCE(_p.cashrcpt_void, false)) THEN
    RAISE EXCEPTION 'Cannot post cashrcpt % because the document has been voided.', _p.cashrcpt_docnumber;
  END IF;

  _predist := COALESCE(_p.cashrcpt_distdate < _p.applydate, false);

  IF (_p.cashrcpt_fundstype IN ('A', 'D', 'M', 'V')) THEN
    SELECT ccpay_id, ccpay_type INTO _ccpayid, _cctype
    FROM ccpay
    WHERE ((ccpay_r_ordernum IN (CAST(pCashrcptid AS TEXT), _p.cashrcpt_docnumber))
       AND (ccpay_status IN ('C', 'A')));

    IF NOT FOUND THEN
      -- the following select seems to work except for xikar - bug 8848. why?
      -- raise warning so there is some visibility if people fall into this path.
      SELECT ccpay_id, ccpay_type INTO _ccpayid, _cctype
      FROM ccpay
      WHERE ((ccpay_order_number IN (CAST(pCashrcptid AS TEXT), _p.cashrcpt_docnumber))
         AND (ccpay_status IN ('C', 'A')));
      IF (NOT FOUND) THEN
        RETURN -8;
      ELSE
        RAISE NOTICE 'PostCashReceipt() found ccpay_id % for order number %/% (ref 8848).',
                      _ccpayid, pCashrcptid, _p.cashrcpt_docnumber;
      END IF;
    END IF;

-- If there is a ccpay entry and the card was charged directly, use the prepaid account
    IF (_cctype = 'C' ) THEN
      _debitAccntid := findPrepaidAccount(_p.cashrcpt_cust_id);
-- If there is a ccpay entry and the card was preauthed and then charged, use the Bank account
    ELSE
      SELECT accnt_id INTO _debitAccntid
      FROM cashrcpt, bankaccnt, accnt
      WHERE ( (cashrcpt_bankaccnt_id=bankaccnt_id)
       AND (bankaccnt_accnt_id=accnt_id)
       AND (cashrcpt_id=pCashrcptid) );
      IF (NOT FOUND) THEN
        RETURN -6;
      END IF;
    END IF;
  ELSE
    SELECT accnt_id INTO _debitAccntid
    FROM cashrcpt, bankaccnt, accnt
    WHERE ( (cashrcpt_bankaccnt_id=bankaccnt_id)
     AND (bankaccnt_accnt_id=accnt_id)
     AND (cashrcpt_id=pCashrcptid) );
    IF (NOT FOUND) THEN
      RETURN -6;
    END IF;
  END IF;

--  Determine the amount to post to A/R Open Items
  SELECT COALESCE(SUM(cashrcptitem_amount), 0) INTO _postToAR
  FROM cashrcptitem JOIN aropen ON (aropen_id=cashrcptitem_aropen_id)
  WHERE (cashrcptitem_cashrcpt_id=pCashrcptid);
  IF (NOT FOUND) THEN
    _postToAR := 0;
  END IF;

--  Determine the amount to post to Misc. Distributions
  SELECT COALESCE(SUM(cashrcptmisc_amount), 0) INTO _postToMisc
  FROM cashrcptmisc
  WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid);
  IF (NOT FOUND) THEN
    _postToMisc := 0;
  END IF;

--  Determine the amount to post to Discount Credit Memo
  SELECT COALESCE(SUM(cashrcptitem_discount), 0) INTO _postToCM
  FROM cashrcptitem JOIN aropen ON ( (aropen_id=cashrcptitem_aropen_id) AND (aropen_doctype IN ('I', 'D')) )
  WHERE (cashrcptitem_cashrcpt_id=pCashrcptid);
  IF (NOT FOUND) THEN
    _postToCM := 0;
  END IF;
  
--  Check to see if the C/R is over applied
  IF ((_postToAR + _postToMisc) > _p.cashrcpt_amount) THEN
    RETURN -1;
  END IF;

--  Check to see if the C/R is positive amount
  IF (_p.cashrcpt_amount <= 0) THEN
    RETURN -2;
  END IF;

--  Distribute A/R Applications
    FOR _r IN SELECT aropen_id, aropen_doctype, aropen_docnumber, aropen_docdate,
                     aropen_duedate, aropen_curr_id, aropen_curr_rate, aropen_amount,
                     round(aropen_amount - aropen_paid, 2) <=
                        round(currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,abs(cashrcptitem_amount + cashrcptitem_discount),_p.cashrcpt_distdate),2)
                                 AS closed,
                     cashrcptitem_id, cashrcptitem_amount, cashrcptitem_discount,
                     (cashrcptitem_amount / _p.cashrcpt_curr_rate) AS cashrcptitem_amount_base,
		     (cashrcptitem_discount / _p.cashrcpt_curr_rate) AS cashrcptitem_discount_base,
                     round(aropen_paid + 
                       currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,abs(cashrcptitem_amount),_p.cashrcpt_distdate),2) AS new_paid,
                     round(currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,cashrcptitem_discount,_p.cashrcpt_distdate),2) AS new_discount
              FROM cashrcptitem JOIN aropen ON (aropen_id=cashrcptitem_aropen_id)
              WHERE ((cashrcptitem_cashrcpt_id=pCashrcptid)
               AND (NOT _predist OR aropen_doctype IN ('C','R'))) LOOP
  
  --  Handle discount 
      IF (_r.cashrcptitem_discount_base > 0) THEN
        PERFORM postCashReceiptDisc(_r.cashrcptitem_id, pJournalNumber);
      END IF;
     
  --  Update the aropen item to post the paid amount
      UPDATE aropen
      SET aropen_paid = _r.new_paid + _r.new_discount,
          aropen_open = (NOT _r.closed),
          aropen_closedate = CASE WHEN _r.closed THEN _p.cashrcpt_distdate END
      WHERE (aropen_id=_r.aropen_id);
  
  --  Cache the running amount posted
      _posted_base := _posted_base + _r.cashrcptitem_amount_base;
      _posted := _posted + _r.cashrcptitem_amount;
 
  --  Record the cashrcpt application
    IF (_r.aropen_doctype IN ('I','D')) THEN
      INSERT INTO arapply
      ( arapply_cust_id,
        arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
        arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
        arapply_fundstype, arapply_refnumber, arapply_reftype, arapply_ref_id,
        arapply_applied, arapply_closed,
        arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_username,
        arapply_curr_id )
      VALUES
      ( _p.cashrcpt_cust_id,
        -1, 'K', _p.cashrcpt_number,
        _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
        _p.cashrcpt_fundstype, _p.cashrcpt_docnumber, 'CRA', _r.cashrcptitem_id,
        round(_r.cashrcptitem_amount, 2), _r.closed,
        _p.applydate, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), _p.cashrcpt_curr_id);
    ELSE
      INSERT INTO arapply
      ( arapply_cust_id,
        arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
        arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
        arapply_fundstype, arapply_refnumber, arapply_reftype, arapply_ref_id,
        arapply_applied, arapply_closed, arapply_postdate, arapply_distdate,
        arapply_journalnumber, arapply_username, arapply_curr_id )
      VALUES
      ( _p.cashrcpt_cust_id,
        _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
        -1, 'R', _p.cashrcpt_number,
        '', '', 'CRA', _r.cashrcptitem_id,
        round(abs(_r.cashrcptitem_amount), 2), _r.closed,
        _p.applydate, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), _p.cashrcpt_curr_id );
    END IF;
  
      _exchGain := arCurrGain(_r.aropen_id,_p.cashrcpt_curr_id, abs(_r.cashrcptitem_amount),
                             _p.cashrcpt_distdate);

       PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                          (_r.aropen_doctype || '-' || _r.aropen_docnumber),
                          CASE WHEN _r.aropen_doctype != 'R' THEN _arAccntid
                          ELSE findDeferredAccount(_p.cashrcpt_cust_id) END, 
                          round(_r.cashrcptitem_amount_base + _exchGain, 2),
                          _p.cashrcpt_distdate, _p.custnote, pCashrcptid );      
                          
      IF (_exchGain <> 0) THEN
          PERFORM insertIntoGLSeries(_sequence, 'A/R', 'CR',
                 _r.aropen_doctype || '-' || _r.aropen_docnumber,
                 getGainLossAccntId(
                   CASE WHEN _r.aropen_doctype != 'R' THEN _arAccntid
                   ELSE findDeferredAccount(_p.cashrcpt_cust_id) END
                 ), round(_exchGain, 2) * -1,
                 _p.cashrcpt_distdate, _p.custnote, pCashrcptid);
      END IF;

    END LOOP;

--  Distribute Misc. Applications
  FOR _r IN SELECT cashrcptmisc_id, cashrcptmisc_accnt_id, cashrcptmisc_amount,
                   (cashrcptmisc_amount / cashrcpt_curr_rate) AS cashrcptmisc_amount_base,
                   cashrcptmisc_notes, cashrcpt_curr_id
            FROM cashrcptmisc JOIN
                 cashrcpt ON (cashrcptmisc_cashrcpt_id = cashrcpt_id)
            WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid)  LOOP

--  Cache the running amount posted
    _posted_base := (_posted_base + _r.cashrcptmisc_amount_base);
    _posted := (_posted + _r.cashrcptmisc_amount);

--  Record the cashrcpt application
    INSERT INTO arapply
    ( arapply_cust_id,
      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
      arapply_fundstype, arapply_refnumber,
      arapply_applied, arapply_closed,
      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_username,
      arapply_curr_id, arapply_reftype, arapply_ref_id )
    VALUES
    ( _p.cashrcpt_cust_id,
      -1, 'K', '',
      -1, 'Misc.', '',
      _p.cashrcpt_fundstype, _p.cashrcpt_docnumber,
      round(_r.cashrcptmisc_amount, 2), TRUE,
      _p.applydate, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), 
      _r.cashrcpt_curr_id, 'CRD', _r.cashrcptmisc_id );
    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR', _r.cashrcptmisc_notes,
                                _r.cashrcptmisc_accnt_id,
                                round(_r.cashrcptmisc_amount_base, 2),
                                _p.cashrcpt_distdate, _p.custnote, pCashrcptid );

  END LOOP;

--  Post any remaining Cash to an A/R Cash Despoit (Credit Memo)
--  this credit memo may absorb an occasional currency exchange rounding error
  IF (round(_posted_base, 2) < round(_p.cashrcpt_amount_base, 2)) THEN
    _comment := ('Unapplied from ' || _p.cashrcpt_fundstype || '-' || _p.cashrcpt_docnumber);
    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                                _comment,
                                _p.prepaid_accnt_id,
                                round(_p.cashrcpt_amount_base, 2) -
                                                        round(_posted_base, 2),
                                _p.cashrcpt_distdate, _p.custnote, pCashrcptid );
    SELECT fetchArMemoNumber() INTO _arMemoNumber;
    IF(_p.cashrcpt_usecustdeposit) THEN
      -- Post Customer Deposit
      SELECT createARCashDeposit(_p.cashrcpt_cust_id, _arMemoNumber, '',
                                 _p.cashrcpt_distdate, (_p.cashrcpt_amount - _posted),
                                 _comment, pJournalNumber, _p.cashrcpt_curr_id) INTO _aropenid;
    ELSE
      -- Post A/R Credit Memo
      _aropenid := createARCreditMemo(NULL, _p.cashrcpt_cust_id, _arMemoNumber, '',
                                _p.cashrcpt_distdate, (_p.cashrcpt_amount - _posted),
                                _comment, -1, -1, -1, _p.cashrcpt_distdate, -1, NULL, 0,
                                pJournalNumber, _p.cashrcpt_curr_id, _arAccntid);
    END IF;

    IF (_ccpayid IS NOT NULL) THEN
      INSERT INTO payaropen (payaropen_ccpay_id, payaropen_aropen_id,
                             payaropen_amount,   payaropen_curr_id
                   ) VALUES (_ccpayid,           _aropenid,
                             _p.cashrcpt_amount, _p.cashrcpt_curr_id);
    END IF;

    -- Create Cash Receipt Item to capture posting
    IF (_predist=false) THEN
      INSERT INTO cashrcptitem
        ( cashrcptitem_cashrcpt_id, cashrcptitem_aropen_id, cashrcptitem_amount, cashrcptitem_applied )
      VALUES
        ( pCashrcptid, _aropenid, (_p.cashrcpt_amount - _posted), false );
    END IF;

  ELSIF (round(_posted_base, 2) > round((_p.cashrcpt_amount_base), 2)) THEN
    PERFORM insertIntoGLSeries(_sequence, 'A/R', 'CR',
                   'Currency Exchange Rounding - ' || _p.cashrcpt_docnumber,
                   getGainLossAccntId(_debitAccntid),
                   round(_posted_base, 2) - round((_p.cashrcpt_amount_base + _p.cashrcpt_discount_base), 2),
                   _p.cashrcpt_distdate, _p.custnote, pCashrcptid);
  END IF;

--  Debit Cash
  PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                    (_p.cashrcpt_fundstype || '-' || _p.cashrcpt_docnumber),
                     _debitAccntid, round(_p.cashrcpt_amount_base, 2) * -1, 
                     _p.cashrcpt_distdate,
                     _p.custnote, pCashrcptid );

  PERFORM postGLSeries(_sequence, pJournalNumber);

  -- convert the cashrcptitem records to applications against the cm/cd if we are _predist
  IF(_predist=true) THEN
    FOR _r IN SELECT *
              FROM cashrcptitem
              WHERE ((cashrcptitem_cashrcpt_id=pCashrcptid)
                AND (cashrcptitem_amount > 0)) LOOP

      -- Handle discount if applicable
      IF (_r.cashrcptitem_discount > 0) THEN
        PERFORM postCashReceiptDisc(_r.cashrcptitem_id, pJournalNumber);
      END IF;
      
      INSERT INTO arcreditapply (arcreditapply_source_aropen_id, arcreditapply_target_aropen_id,
                                 arcreditapply_amount, arcreditapply_curr_id)
                          VALUES(_aropenid, _r.cashrcptitem_aropen_id,
                                 _r.cashrcptitem_amount, _p.cashrcpt_curr_id);
      _posted := (_posted + _r.cashrcptitem_amount);
      
    END LOOP;

    PERFORM postArCreditMemoApplication(_aropenid, _p.applydate);
    
    -- If there is any left over go ahead and create an additional cashrcptitem record for it with the amount
    IF (round(_posted, 2) < round(_p.cashrcpt_amount, 2)) THEN
      INSERT INTO cashrcptitem
        ( cashrcptitem_cashrcpt_id, cashrcptitem_aropen_id, cashrcptitem_amount, cashrcptitem_applied )
      VALUES
        ( pCashrcptid, _aropenid, (_p.cashrcpt_amount - _posted), false );
    END IF;
  END IF;

--  Update the posted cashrcpt
  UPDATE cashrcpt SET cashrcpt_posted=TRUE,
                      cashrcpt_posteddate=CURRENT_DATE,
                      cashrcpt_postedby=getEffectiveXtUser()
  WHERE (cashrcpt_id=pCashrcptid);

  RETURN 1;

END;

Function: public.postcashreceiptdisc(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptItemId ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _r RECORD;
  _t RECORD;
  _v RECORD;
  _ardiscountid INTEGER;
  _arMemoNumber TEXT;
  _arAccntid INTEGER;
  _discountAccntid INTEGER;
  _comment      TEXT;
  _discprcnt NUMERIC;
  _check INTEGER;

BEGIN

    -- Fetch base records for processing
    SELECT aropen_id, aropen_doctype, aropen_amount,
           cashrcptitem_discount,
           cashrcpt_cust_id, cashrcpt_distdate, cashrcpt_applydate,
           cashrcpt_curr_id, cashrcpt_fundstype, cashrcpt_docnumber,
           round(currToCurr(cashrcpt_curr_id, aropen_curr_id, cashrcptitem_discount, cashrcpt_distdate),2) AS aropen_discount
      INTO _r
    FROM cashrcptitem 
      JOIN cashrcpt ON (cashrcptitem_cashrcpt_id=cashrcpt_id)
      JOIN aropen ON ( (aropen_id=cashrcptitem_aropen_id) AND (aropen_doctype IN ('I', 'D')) )
    WHERE (cashrcptitem_id=pCashrcptItemId);

    -- Get discount account
    _discountAccntid := findardiscountaccount(_r.cashrcpt_cust_id);
  
    IF (_r.cashrcptitem_discount > 0) THEN
      --  Determine discount percentage
      _discprcnt := _r.aropen_discount / _r.aropen_amount;

      SELECT fetchArMemoNumber() INTO _arMemoNumber;
      _comment := 'Discount Credit from ' || _r.cashrcpt_fundstype || '-' || _r.cashrcpt_docnumber;

      -- Create misc credit memo record
      _ardiscountid := nextval('aropen_aropen_id_seq');
      INSERT INTO aropen (
        aropen_id, aropen_docdate, aropen_duedate, aropen_doctype, 
        aropen_docnumber, aropen_curr_id, aropen_posted, aropen_amount) 
      VALUES (
        _ardiscountid, _r.cashrcpt_distdate, _r.cashrcpt_distdate, 'C', 
        _arMemoNumber, _r.cashrcpt_curr_id, false,_r.cashrcptitem_discount);
        
      IF (fetchMetricBool('CreditTaxDiscount')) THEN
        --  proportional tax credits calculated and implemented for the credit memo generated by the discount
        IF (_r.aropen_doctype  = 'I') THEN
          -- Tax for invoices
          SELECT aropen_cobmisc_id AS invcheadid, 
                 invchead_curr_id, 
                 invchead_invcdate INTO _t
          FROM aropen
            LEFT OUTER JOIN invchead ON (aropen_cobmisc_id = invchead_id) 
            LEFT OUTER JOIN invcitem ON (invchead_id = invcitem_invchead_id)
          WHERE aropen_id = _r.aropen_id;

          FOR _v IN SELECT tax_sales_accnt_id,
                           tax_id, 
                           round(sum(taxdetail_tax), 2) AS tax,
                           currToBase(_t.invchead_curr_id, round(sum(taxdetail_tax), 2), _t.invchead_invcdate) AS taxbasevalue
          FROM tax 
            JOIN calculateTaxDetailSummary('I', _t.invcheadid, 'T') ON (taxdetail_tax_id=tax_id)
            GROUP BY tax_id, tax_sales_accnt_id 
          LOOP
            INSERT INTO aropentax(
              taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
              taxhist_percent, taxhist_amount, taxhist_tax, 
              taxhist_docdate, taxhist_basis)
            VALUES (
              _ardiscountid, getadjustmenttaxtypeid(), _v.tax_id, 
              0.00, 0.00, (round((_v.tax * _discprcnt), 2) * -1), 
              _r.cashrcpt_distdate, 0.00);
          END LOOP;

        ELSIF (_r.aropen_doctype  = 'D') THEN
          -- Tax for debit memos
          INSERT INTO aropentax(
            taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
            taxhist_percent, taxhist_amount, taxhist_tax, 
            taxhist_docdate, taxhist_basis)
          SELECT
            _ardiscountid, taxhist_taxtype_id, taxhist_tax_id, 
            0.00, 0.00, (round((taxhist_tax * _discprcnt), 2) * -1),  
            _r.cashrcpt_distdate, 0.00
          FROM aropentax
          WHERE (taxhist_parent_id=_r.aropen_id);
              
        END IF;
      END IF; -- End taxes

      -- Create credit memo for discount
      SELECT createARCreditMemo(_ardiscountid, _r.cashrcpt_cust_id, _arMemoNumber, '',
                                _r.cashrcpt_distdate, _r.cashrcptitem_discount,
                                _comment, -1, -1, _discountAccntid, _r.cashrcpt_distdate,
                                -1, NULL, 0,
                                pJournalNumber, _r.cashrcpt_curr_id) INTO _ardiscountid;

      -- Apply discount credit memo
      INSERT INTO arcreditapply ( 
        arcreditapply_source_aropen_id, arcreditapply_target_aropen_id,
        arcreditapply_amount, arcreditapply_curr_id )
      VALUES ( 
        _ardiscountid, _r.aropen_id, _r.cashrcptitem_discount, _r.cashrcpt_curr_id );
 
      SELECT postARCreditMemoApplication(_ardiscountid, _r.cashrcpt_applydate) INTO _check;
      IF (_check < 0) THEN
        RAISE EXCEPTION 'Error posting discount credit memo application. Code %', _check;
      END IF;
        
   END IF; -- End handle Discount

   RETURN 1;

END;

Function: public.postcccashreceipt(pamount integer, pdoctype integer, pdocid text, pccpay numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _aropenid     INTEGER;
  _bankaccnt_id INTEGER;
  _c            RECORD;
  _ccOrderDesc  TEXT;
  _journal      INTEGER;
  _realaccnt    INTEGER;
  _return       INTEGER := 0;

BEGIN
  SELECT * INTO _c
     FROM ccpay, ccard, custinfo
     WHERE ( (ccpay_id = pCCpay)
       AND   (ccpay_ccard_id = ccard_id)
       AND   (ccpay_cust_id = cust_id) );

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot find the Credit Card transaction information [xtuple: postCCcashReceipt, -11, %]',
                    pCCpay;
  END IF;

  IF (pamount IS NOT NULL) THEN
    _c.ccpay_amount = pamount;
  END IF;

  SELECT bankaccnt_id, bankaccnt_accnt_id INTO _bankaccnt_id, _realaccnt
  FROM ccbank JOIN bankaccnt ON (ccbank_bankaccnt_id=bankaccnt_id)
  WHERE (ccbank_ccard_type=_c.ccard_type);

  IF (_bankaccnt_id IS NULL) THEN
    RAISE EXCEPTION 'Cannot find the default Bank Account for this Credit Card [xtuple: postCCcredit, -1, %]',
                    _c.ccard_type;
  END IF;

  _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_order_number::TEXT ||
		   '-' || _c.ccpay_order_number_seq::TEXT);

  _journal := fetchJournalNumber('C/R');

  IF (pdoctype = 'cashrcpt') THEN
    IF (COALESCE(pdocid, -1) < 0) THEN
      INSERT INTO cashrcpt (
        cashrcpt_cust_id,   cashrcpt_amount,     cashrcpt_curr_id,
        cashrcpt_fundstype, cashrcpt_docnumber,  cashrcpt_notes,
        cashrcpt_distdate,  cashrcpt_bankaccnt_id,
        cashrcpt_usecustdeposit
      ) VALUES (
        _c.ccpay_cust_id,   _c.ccpay_amount,     _c.ccpay_curr_id,
        _c.ccard_type,      _c.ccpay_r_ordernum, _ccOrderDesc,
        CURRENT_DATE,       _bankaccnt_id,
        fetchMetricBool('EnableCustomerDeposits'))
      RETURNING cashrcpt_id INTO _return;
    ELSE
      UPDATE cashrcpt
      SET cashrcpt_cust_id=_c.ccpay_cust_id,
          cashrcpt_amount=_c.ccpay_amount,
          cashrcpt_curr_id=_c.ccpay_curr_id,
          cashrcpt_fundstype=_c.ccard_type,
          cashrcpt_docnumber=_c.ccpay_r_ordernum,
          cashrcpt_notes=_ccOrderDesc,
          cashrcpt_distdate=CURRENT_DATE,
          cashrcpt_bankaccnt_id=_bankaccnt_id
      WHERE (cashrcpt_id=pdocid);
      _return := pdocid;
    END IF;

  ELSIF (pdoctype = 'cohead') THEN
    SELECT createARCreditMemo(NULL,               _c.ccpay_cust_id,
                             fetchArMemoNumber(), cohead_number,
                             CURRENT_DATE,        _c.ccpay_amount,
                             'Unapplied from ' || _ccOrderDesc,
                             NULL,                NULL, NULL,
                             CURRENT_DATE,        NULL,
                             cohead_salesrep_id,  NULL,
                             _journal,            _c.ccpay_curr_id,
                             NULL,                pCCpay) INTO _aropenid
      FROM cohead
     WHERE cohead_id = pdocid;
    IF (COALESCE(_aropenid, -1) < 0) THEN       -- coalesce handles not-found case
      RAISE EXCEPTION '[xtuple: createARCreditMemo, %]', _aropenid;
    END IF;

    INSERT INTO payaropen (payaropen_ccpay_id, payaropen_aropen_id,
                           payaropen_amount,   payaropen_curr_id)
                  VALUES  (pccpay,             _aropenid,
                           _c.ccpay_amount,    _c.ccpay_curr_id);
    INSERT INTO aropenalloc (aropenalloc_aropen_id, aropenalloc_doctype, aropenalloc_doc_id,
                             aropenalloc_amount,    aropenalloc_curr_id)
                     VALUES (_aropenid, 'S',          pdocid,
                             _c.ccpay_amount,    _c.ccpay_curr_id);
    _return := _aropenid;
  END IF;

  PERFORM insertGLTransaction(_journal, 'A/R', 'CR', _ccOrderDesc, 
                              ('Cash Receipt from Credit Card ' || _c.cust_name),
                              findPrepaidAccount(_c.ccpay_cust_id),
                              _realaccnt,
                              NULL,
			      ROUND(currToBase(_c.ccpay_curr_id,
					       _c.ccpay_amount,
					       _c.ccpay_transaction_datetime::DATE),2),
                              CURRENT_DATE);

  RETURN _return;
END;

Function: public.postcccredit(integer, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCCpay	ALIAS FOR $1;
  preftype      ALIAS FOR $2;
  prefid        ALIAS FOR $3;
  _c		RECORD;
  _ccOrderDesc	TEXT;
  _cglaccnt     INTEGER;
  _dglaccnt	INTEGER;
  _glseriesres  INTEGER;
  _notes	TEXT := 'Credit via Credit Card';
  _r		RECORD;
  _sequence	INTEGER;
  _dmaropenid	INTEGER;

BEGIN
  IF ((preftype = 'cohead') AND NOT EXISTS(SELECT cohead_id
					     FROM cohead
					     WHERE (cohead_id=prefid))) THEN
    RAISE EXCEPTION 'Cannot find original Sales Order for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
                    pCCpay, preftype, prefid;
  ELSIF ((preftype = 'aropen') AND NOT EXISTS(SELECT aropen_id
                                                FROM aropen
                                                WHERE (aropen_id=prefid))) THEN
    RAISE EXCEPTION 'Cannot find original A/R Open record for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
                    pCCpay, preftype, prefid;
  ELSIF ((preftype = 'cmhead') AND NOT EXISTS(SELECT cmhead_id
                                                FROM cmhead
                                               WHERE cmhead_id=prefid)) THEN
    RAISE EXCEPTION 'Cannot find original Credit Memo record for this Credit Card credit [xtuple: postCCcredit, -2, %, %, %]',
                    pCCpay, preftype, prefid;
  END IF;

  SELECT * INTO _c
     FROM ccpay
     JOIN ccard  ON (ccpay_ccard_id = ccard_id)
     JOIN ccbank ON (ccard_type=ccbank_ccard_type)
    WHERE (ccpay_id = pCCpay);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot find the record for this Credit Card credit [xtuple: postCCcredit, -3, %, %, %]',
                    pCCpay, preftype, prefid;
  END IF;

  IF (preftype = 'cohead') THEN
    _dglaccnt := findPrepaidAccount(_c.ccpay_cust_id);
  ELSE
    _dglaccnt := findARAccount(_c.ccpay_cust_id);
  END IF;

  SELECT bankaccnt_accnt_id INTO _cglaccnt
  FROM bankaccnt
  WHERE (bankaccnt_id=_c.ccbank_bankaccnt_id);

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot find the default Bank Account for this Credit Card [xtuple: postCCcredit, -1, %]',
                    pCCpay;
  END IF;

  IF (_c.ccpay_type != 'R') THEN
    RAISE EXCEPTION 'This Credit Card transaction is not a credit/refund [xtuple: postCCcredit, -4, %]',
                    pCCpay;
  END IF;

  _sequence := fetchGLSequence();

  IF (_c.ccpay_r_ref IS NOT NULL) THEN
    _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_r_ref);
  ELSE
    _ccOrderDesc := (_c.ccard_type || '-' || _c.ccpay_order_number::TEXT ||
		     '-' || COALESCE(_c.ccpay_order_number_seq::TEXT, ''));
  END IF;

  _glseriesres := insertIntoGLSeries(_sequence, 'A/R', 'CC', _ccOrderDesc,
                                     _dglaccnt,
                                     ROUND(currToBase(_c.ccpay_curr_id,
                                                      _c.ccpay_amount,
                                                      _c.ccpay_transaction_datetime::DATE), 2) * -1,
                                     CURRENT_DATE, _notes);
  IF (_glseriesres < 0) THEN
    RAISE EXCEPTION 'Could not write debit side of Credit Card credit to the G/L [xtuple: insertIntoGLSeries, %]',
                    _glseriesres;
  END IF;

  _glseriesres := insertIntoGLSeries(_sequence, 'A/R', 'CC', _ccOrderDesc,
                                     _cglaccnt,
                                     ROUND(currToBase(_c.ccpay_curr_id,
                                                      _c.ccpay_amount,
                                                      _c.ccpay_transaction_datetime::DATE),2),
                                     CURRENT_DATE, _notes);
  IF (_glseriesres < 0) THEN
    RAISE EXCEPTION 'Could not write credit side of Credit Card credit to the G/L [xtuple: insertIntoGLSeries, %]',
                    _glseriesres;
  END IF;

  _glseriesres := postGLSeries(_sequence, fetchJournalNumber('C/R') );
  IF (_glseriesres < 0) THEN
    RAISE EXCEPTION 'Could not post Credit Card credit to the G/L [xtuple: postglseries, %]',
                    _glseriesres;
  END IF;

  IF (preftype = 'aropen') THEN
    SELECT * INTO _r
    FROM aropen
    WHERE (aropen_id=prefid);

  ELSE
    SELECT aropen.* INTO _r
    FROM ccpay n
      JOIN ccpay o  ON (o.ccpay_id=n.ccpay_ccpay_id)
      JOIN payaropen ON (payaropen_ccpay_id=o.ccpay_id)
      JOIN aropen ON (payaropen_aropen_id=aropen_id)
    WHERE (n.ccpay_id=pCCpay);
  END IF;

  IF (FOUND) THEN
    SELECT createardebitmemo(
            NULL, 
            _r.aropen_cust_id, NULL, fetchARMemoNumber(),
            _r.aropen_ordernumber, current_date, _c.ccpay_amount,
            _notes,
            -1, -1, -1, CURRENT_DATE, -1, NULL, 0, 
            _r.aropen_curr_id) INTO _dmaropenid;

    IF (_r.aropen_open) THEN
      PERFORM applyARCreditMemoToBalance(_r.aropen_id, _dmaropenid);
      PERFORM postARCreditMemoApplication(_r.aropen_id);
    END IF;
    
  END IF;

  IF (preftype = 'cohead') THEN
    INSERT INTO payco (
      payco_ccpay_id, payco_cohead_id, payco_amount, payco_curr_id 
    ) VALUES (
      pCCpay, prefid, 0 - _c.ccpay_amount, _c.ccpay_curr_id
    );
  END IF;

  RETURN 0;

END;

Function: public.postccvoid(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pccpayid ALIAS FOR $1;

BEGIN
  -- for now this is very simple: mark the ccpay record voided.
  -- in the future this might be expanded to back out changes to other tables
  -- but for now the VOID request is sent to the credit card processing company
  -- before those other tables are modified.

  UPDATE ccpay SET ccpay_status = 'V' WHERE (ccpay_id=pccpayid);

  IF (NOT FOUND) THEN
    RETURN -1;
  END IF;

  RETURN 0;

END;

Function: public.postcheck(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcheckid		ALIAS FOR $1;
  _journalNumber	INTEGER := $2;
  _amount_base		NUMERIC := 0;
  _credit_glaccnt	INTEGER;
  _exchGain		NUMERIC := 0;
  _exchGainTmp		NUMERIC := 0;
  _gltransNote		TEXT;
  _p			RECORD;
  _r			RECORD;
  _t			RECORD;
  _sequence		INTEGER;
  _test                 INTEGER;
  _cm                   BOOLEAN;
  _amount_check         NUMERIC := 0;

BEGIN

  _cm := FALSE;

  SELECT fetchGLSequence() INTO _sequence;
  IF (_journalNumber IS NULL) THEN
    _journalNumber := fetchJournalNumber('AP-CK');
  END IF;

  SELECT checkhead.*,
         checkhead_amount / checkhead_curr_rate AS checkhead_amount_base,
         bankaccnt_accnt_id AS bankaccntid INTO _p
  FROM checkhead
   JOIN bankaccnt ON (checkhead_bankaccnt_id=bankaccnt_id)
  WHERE (checkhead_id=pcheckid);

  IF (FOUND) THEN
    IF (_p.checkhead_recip_type = 'V') THEN
      SELECT
        vend_number AS checkrecip_number,
        vend_name AS checkrecip_name,
        findAPAccount(vend_id) AS checkrecip_accnt_id,
        'A/P'::text AS checkrecip_gltrans_source
        INTO _t
      FROM vendinfo
      WHERE (vend_id=_p.checkhead_recip_id);
    ELSIF (_p.checkhead_recip_type = 'C') THEN
      SELECT
        cust_number AS checkrecip_number,
        cust_name AS checkrecip_name,
        findARAccount(cust_id) AS checkrecip_accnt_id,
        'A/R'::text AS checkrecip_gltrans_source
        INTO _t
      FROM custinfo
      WHERE (cust_id=_p.checkhead_recip_id); 
    ELSIF (_p.checkhead_recip_type = 'T') THEN
      SELECT
        taxauth_code AS checkrecip_number,
        taxauth_name AS checkrecip_name,
        taxauth_accnt_id AS checkrecip_accnt_id,
        'G/L'::text AS checkrecip_gltrans_source
        INTO _t
      FROM taxauth
      WHERE (taxauth_id=_p.checkhead_recip_id);
    ELSE
      RETURN -11;
    END IF;
  ELSE
    RETURN -11;
  END IF;

  IF (_p.checkhead_posted) THEN
    RETURN -10;
  END IF;

  IF (_p.checkhead_recip_type = 'C') THEN
    SELECT checkitem_id FROM checkitem INTO _test
    WHERE (checkitem_checkhead_id=pcheckid)
    LIMIT 1;
    IF (FOUND) THEN
      _cm := TRUE;
    END IF;
  END IF;

  _gltransNote := _t.checkrecip_number || '-' || _t.checkrecip_name;

  IF (_p.checkhead_misc AND NOT _cm) THEN
    IF (COALESCE(_p.checkhead_expcat_id, -1) < 0) THEN
      IF (_p.checkhead_recip_type = 'V') THEN
	PERFORM createAPCreditMemo( _p.checkhead_recip_id, _journalNumber,
				    CAST(fetchAPMemoNumber() AS text), '',
				    _p.checkhead_checkdate, _p.checkhead_amount,
				    _gltransNote || ' ' || _p.checkhead_notes,
				    -1, _p.checkhead_checkdate,
				    -1, _p.checkhead_curr_id );
	_credit_glaccnt := findAPPrepaidAccount(_p.checkhead_recip_id);

      ELSIF (_p.checkhead_recip_type = 'C') THEN
	PERFORM createARDebitMemo(NULL, _p.checkhead_recip_id, NULL,
	  			     fetchARMemoNumber(), '',
				     _p.checkhead_checkdate, _p.checkhead_amount,
				     _gltransNote || ' ' || _p.checkhead_notes,
                                     -1, -1, -1, _p.checkhead_checkdate, -1, NULL, 0,
				     _p.checkhead_curr_id );
        _credit_glaccnt := findPrepaidAccount(_p.checkhead_recip_id);
      ELSIF (_p.checkhead_recip_type = 'T') THEN
	-- TODO: should we create a credit memo for the tax authority? how?
	_credit_glaccnt := _t.checkrecip_accnt_id;

      END IF; -- recip type

    ELSE
      IF (_cm) THEN
        _credit_glaccnt := findARAccount(_p.checkhead_recip_id);
      ELSE
        SELECT expcat_exp_accnt_id INTO _credit_glaccnt
        FROM expcat
        WHERE (expcat_id=_p.checkhead_expcat_id);
        IF (NOT FOUND) THEN
          RETURN -12;
        END IF;
      END IF;
    END IF;

    IF (COALESCE(_credit_glaccnt, -1) < 0) THEN
      RETURN -13;
    END IF;

    PERFORM insertIntoGLSeries( _sequence, _t.checkrecip_gltrans_source, 'CK',
				CAST(_p.checkhead_number AS TEXT),
				_credit_glaccnt,
				round(_p.checkhead_amount_base, 2) * -1,
				_p.checkhead_checkdate, _gltransNote, pcheckid );

    _amount_base := _p.checkhead_amount_base;

  ELSE
    FOR _r IN SELECT checkitem_amount, checkitem_discount,
                     CASE WHEN (checkitem_apopen_id IS NOT NULL) THEN
                       checkitem_amount / apopen_curr_rate
                     ELSE
                       currToBase(checkitem_curr_id,
                                  checkitem_amount,
                                  COALESCE(checkitem_docdate, _p.checkhead_checkdate)) 
                     END AS checkitem_amount_base,
                     currTocurr(checkitem_curr_id, _p.checkhead_curr_id,
                                  checkitem_amount,
                                  _p.checkhead_checkdate) AS amount_check,
                     apopen_id, apopen_doctype, apopen_docnumber,
                     aropen_id, aropen_doctype, aropen_docnumber,
                     checkitem_curr_id, checkitem_curr_rate, apopen_curr_rate,
                     COALESCE(checkitem_docdate, _p.checkhead_checkdate) AS docdate
              FROM (checkitem LEFT OUTER JOIN
		    apopen ON (checkitem_apopen_id=apopen_id)) LEFT OUTER JOIN
		    aropen ON (checkitem_aropen_id=aropen_id)
              WHERE (checkitem_checkhead_id=pcheckid) LOOP

      _exchGainTmp := 0;
      IF (_r.apopen_id IS NOT NULL) THEN
	--  take the discount if specified before we do anything else
        IF(_r.checkitem_discount > 0.0) THEN
          PERFORM createAPDiscount(_r.apopen_id, _r.checkitem_discount);
        END IF;

        UPDATE apopen

        SET apopen_paid = round(apopen_paid + _r.checkitem_amount, 2),
            apopen_open = round(apopen_amount, 2) >
			  round(apopen_paid + _r.checkitem_amount, 2),
            apopen_closedate = CASE WHEN (round(apopen_amount, 2) <=
			                  round(apopen_paid + _r.checkitem_amount, 2)) THEN _p.checkhead_checkdate END
        WHERE (apopen_id=_r.apopen_id);

	--  Post the application
        INSERT INTO apapply
        ( apapply_vend_id, apapply_postdate, apapply_username,
          apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
          apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
          apapply_journalnumber, apapply_amount, apapply_curr_id, apapply_checkhead_id )
        VALUES
        ( _p.checkhead_recip_id, _p.checkhead_checkdate, getEffectiveXtUser(),
          -1, 'K', _p.checkhead_number,
          _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
          _journalNumber, _r.checkitem_amount, _r.checkitem_curr_id, _p.checkhead_id );
      END IF; -- if check item's apopen_id is not null

      IF (_r.aropen_id IS NOT NULL) THEN

        UPDATE aropen
        SET aropen_paid = round(aropen_paid + _r.checkitem_amount, 2),
            aropen_open = round(aropen_amount, 2) >
			  round(aropen_paid + _r.checkitem_amount, 2),
            aropen_closedate = CASE WHEN (round(aropen_amount, 2) <=
			                  round(aropen_paid + _r.checkitem_amount, 2)) THEN _p.checkhead_checkdate END
        WHERE (aropen_id=_r.aropen_id);

	--  Post the application
        INSERT INTO arapply
        ( arapply_cust_id, arapply_postdate, arapply_distdate, arapply_username,
          arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
          arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
          arapply_journalnumber, arapply_applied, arapply_curr_id )
        VALUES
        ( _p.checkhead_recip_id, _p.checkhead_checkdate, _p.checkhead_checkdate, getEffectiveXtUser(),
          _r.aropen_id,_r.aropen_doctype, _r.aropen_docnumber,
          -1, 'K',_p.checkhead_number ,
          _journalNumber, _r.checkitem_amount, _r.checkitem_curr_id );

      END IF; -- if check item's aropen_id is not null

      IF (_r.apopen_id IS NOT NULL) THEN
        SELECT apCurrGain(_r.apopen_id,_r.checkitem_curr_id, _r.checkitem_amount,
                        _p.checkhead_checkdate)
              INTO _exchGainTmp;
      ELSIF (_r.aropen_id IS NOT NULL) THEN
        SELECT arCurrGain(_r.aropen_id,_r.checkitem_curr_id, _r.checkitem_amount,
                        _p.checkhead_checkdate)
              INTO _exchGainTmp;
      END IF;
      _exchGain := _exchGain + _exchGainTmp;

      PERFORM insertIntoGLSeries( _sequence, _t.checkrecip_gltrans_source,
				  'CK', CAST(_p.checkhead_number AS TEXT),
                                  _t.checkrecip_accnt_id,
                                  round(_r.checkitem_amount_base, 2) * -1,
                                  _p.checkhead_checkdate, _gltransNote, pcheckid );
      IF (_exchGainTmp <> 0) THEN
	PERFORM insertIntoGLSeries( _sequence, _t.checkrecip_gltrans_source,
				    'CK', CAST(_p.checkhead_number AS TEXT),
				    getGainLossAccntId(_t.checkrecip_accnt_id), round(_exchGainTmp,2),
				    _p.checkhead_checkdate, _gltransNote, pcheckid );
      END IF;

      _amount_check := (_amount_check + _r.amount_check);
      _amount_base := (_amount_base + _r.checkitem_amount_base);

    END LOOP;

    IF( (_amount_check - _p.checkhead_amount) <> 0.0 ) THEN 
      _exchGainTmp := currToBase(_p.checkhead_curr_id,
                                 _amount_check - _p.checkhead_amount,
                                 _p.checkhead_checkdate);
      _exchGain := _exchGain + _exchGainTmp;
    END IF;
    --  ensure that the check balances, attribute rounding errors to gain/loss
    IF round(_amount_base, 2) - round(_exchGain, 2) <> round(_p.checkhead_amount_base, 2) THEN
      IF round(_amount_base - _exchGain, 2) = round(_p.checkhead_amount_base, 2) THEN
	PERFORM insertIntoGLSeries( _sequence, _t.checkrecip_gltrans_source,
				    'CK',
				    CAST(_p.checkhead_number AS TEXT),
                                    getGainLossAccntId(_p.bankaccntid),
				    round(_amount_base, 2) -
				      round(_exchGain, 2) -
				      round(_p.checkhead_amount_base, 2),
				    _p.checkhead_checkdate, _gltransNote, pcheckid );
      ELSE
	RAISE EXCEPTION 'checkhead_id % does not balance (% - % <> %)', pcheckid,
	      _amount_base, _exchGain, _p.checkhead_amount_base;
      END IF;
    END IF;
  END IF;

  PERFORM insertIntoGLSeries( _sequence, _t.checkrecip_gltrans_source, 'CK',
			      CAST(_p.checkhead_number AS TEXT),
                              _p.bankaccntid,
			      round(_p.checkhead_amount_base, 2),
                              _p.checkhead_checkdate, _gltransNote, pcheckid );

  PERFORM postGLSeries(_sequence, _journalNumber);

  UPDATE checkhead
  SET checkhead_posted=TRUE,
      checkhead_journalnumber=_journalNumber
  WHERE (checkhead_id=pcheckid);

  RETURN _journalNumber;

END;

Function: public.postchecks(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid ALIAS FOR $1;
  _journalNumber INTEGER;

BEGIN

  SELECT fetchJournalNumber('AP-CK') INTO _journalNumber;

  PERFORM postCheck(checkhead_id, _journalNumber)
  FROM checkhead
  WHERE ( (NOT checkhead_void)
    AND   (NOT checkhead_posted)
    AND   (checkhead_printed)
    AND   (checkhead_bankaccnt_id=pBankaccntid) );

  RETURN _journalNumber;

END;

Function: public.postcomment(ppublic integer, ptext text, psourceid integer, psource text, pcmnttypeid boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _commentid INTEGER;
  _public BOOLEAN;

BEGIN
  _public := COALESCE(pPublic, fetchmetricbool('CommentPublicDefault'));

  INSERT INTO comment
  ( comment_cmnttype_id, comment_source, comment_source_id,
    comment_date, comment_user, comment_text, comment_public )
  VALUES
  ( pCmnttypeid, pSource, pSourceid,
    CURRENT_TIMESTAMP, getEffectiveXtUser(), pText, _public )
  RETURNING comment_id INTO _commentid;

  RETURN _commentid;

END;

Function: public.postcomment(ptext integer, psourceid text, psource integer, pcmnttypeid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

BEGIN
  RETURN postComment(pCmnttypeid, pSource, pSourceid, pText, NULL);
END

Function: public.postcomment(ptext text, psourceid text, psource integer, pcmnttypename text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cmnttypeid INTEGER;

BEGIN
  SELECT cmnttype_id INTO _cmnttypeid
  FROM cmnttype
  WHERE (cmnttype_name=pCmnttypename);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Comment type % not found.', pCmnttypename;
  END IF;

  RETURN postComment(_cmnttypeid, pSource, pSourceid, pText, NULL);
END

Function: public.postcost(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemcostid ALIAS FOR $1;
  _p RECORD;

BEGIN

  SELECT round(currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE),6) AS newcost,
         itemcost_curr_id, CURRENT_DATE AS effective,
         item_number,
         itemcost_stdcost AS oldcost INTO _p
  FROM itemcost, item
  WHERE ((itemcost_item_id=item_id)
    AND  (itemcost_id=pItemcostid));

  IF (_p.newcost IS NULL) THEN
      RAISE EXCEPTION 'There is no valid Exchange Rate for this currency. (%, %)',
                  _p.itemcost_curr_id, _p.effective;
      RETURN FALSE;
  END IF;

  RETURN updateStdCost(pItemcostid, _p.newcost, _p.oldcost, 'Post Cost',
               ('Post Actual Cost to Standard for item ' || _p.item_number));

END;

Function: public.postcountslip(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCntslipid ALIAS FOR $1;
  _p RECORD;
  _comments TEXT;
  _temp TEXT;

BEGIN

  SELECT itemsite_loccntrl, itemsite_controlmethod,
         cntslip_posted, cntslip_lotserial, cntslip_comments,
         cntslip_number, cntslip_qty INTO _p
  FROM cntslip, invcnt, itemsite
  WHERE ( (cntslip_cnttag_id=invcnt_id)
   AND (invcnt_itemsite_id=itemsite_id)
   AND (cntslip_id=pCntslipid) );

  IF (NOT _p.cntslip_posted) THEN
    SELECT ( E'\nCount Slip #' || _p.cntslip_number ||
             ' counted ' || formatQty(_p.cntslip_qty) ) INTO _comments;

--  Add the Location name if the itemsite is MLC
    IF (_p.itemsite_loccntrl) THEN
      SELECT ( ', Location:' || location_name ) INTO _temp
      FROM location, cntslip
      WHERE ( (cntslip_location_id=location_id)
       AND (cntslip_id=pCntslipid) );

      _comments := (_comments || _temp);
    END IF;

--  Add the Lot/Serial if the itemsite is Lot or Serial controlled
    IF (_p.itemsite_controlmethod = 'L') THEN
      _comments := (_comments || ( ', Lot #:' || _p.cntslip_lotserial));
    ELSIF (_p.itemsite_controlmethod = 'S') THEN
      _comments := (_comments || ( ', Serial #:' || _p.cntslip_lotserial));
    END IF;

    _comments := (_comments || ' ' || _p.cntslip_comments);

    UPDATE cntslip
    SET cntslip_posted=TRUE
    WHERE (cntslip_id=pCntslipid);

    UPDATE invcnt
    SET invcnt_qoh_after = ( COALESCE(invcnt_qoh_after, 0) + cntslip_qty),
        invcnt_comments = (invcnt_comments || _comments)
    FROM cntslip
    WHERE ( (cntslip_cnttag_id=invcnt_id)
     AND (cntslip_id=pCntslipid) );

    RETURN 1;

  ELSE
    RETURN -1;
  END IF;

END;

Function: public.postcounttag(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcntid ALIAS FOR $1;
  pThaw ALIAS FOR $2;
  _avgCostingMethod TEXT;
  _invhistid INTEGER;
  _postDate TIMESTAMP;
  _runningQty NUMERIC;
  _errorCode INTEGER;
  _itemlocSeries INTEGER := 0;
  _hasDetail BOOLEAN;
  _p RECORD;
  _itemloc RECORD;
  _cntslip RECORD;
  _lsid INTEGER;

BEGIN

  SELECT COALESCE(fetchMetricText('CountAvgCostMethod'), 'STD') INTO _avgCostingMethod;

  SELECT invcnt_id, invcnt_tagnumber, invcnt_qoh_after,
         invcnt_location_id,
         item_number,
         itemsite_id, itemsite_freeze,
         itemsite_qtyonhand,
         itemsite_loccntrl, itemsite_location_id,
         CASE WHEN (itemsite_costmethod = 'N') THEN 0
              WHEN ( (itemsite_costmethod = 'A') AND
                     (itemsite_qtyonhand = 0) AND
                     (_avgCostingMethod = 'ACT') ) THEN actcost(itemsite_item_id)
              WHEN ( (itemsite_costmethod = 'A') AND
                     (_avgCostingMethod IN ('ACT', 'AVG')) ) THEN avgcost(itemsite_id)
              ELSE stdcost(itemsite_item_id)
         END AS cost, itemsite_costmethod,
         itemsite_controlmethod,
         itemsite_value INTO _p
  FROM invcnt, itemsite, item
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (invcnt_qoh_after IS NOT NULL)
   AND (NOT invcnt_posted)
   AND (invcnt_id=pInvcntid) );
  IF (FOUND) THEN
-- If the invcnt_location_id is not null then
-- call a separate function so as not to affect
-- the existing functionality.
    IF (_p.invcnt_location_id IS NOT NULL) THEN
      RETURN postCountTagLocation(pInvcntid, pThaw);
    END IF;

    SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;

    IF (_p.itemsite_freeze) THEN
      SELECT invcnt_tagdate INTO _postDate
      FROM invcnt
      WHERE (invcnt_id=pInvcntid) ;
    ELSE
      _postDate = CURRENT_TIMESTAMP;
    END IF;

    _hasDetail = FALSE;

--  Post the detail indicated by cntslips
    IF ( (_p.itemsite_loccntrl) OR
         (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN

      SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;

--  Adjust any existing detail to 0
      FOR _itemloc IN SELECT itemloc_id, itemloc_location_id,
                             itemloc_ls_id, itemloc_qty
                      FROM itemloc
                      WHERE (itemloc_itemsite_id=_p.itemsite_id) LOOP

        _hasDetail = TRUE;

--  Create the itemlocdist flushing records
        INSERT INTO itemlocdist
        ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
          itemlocdist_expiration,
          itemlocdist_itemsite_id, itemlocdist_invhist_id, itemlocdist_flush )
        VALUES
        ( _itemlocSeries, 'I', _itemloc.itemloc_id,
          endOfTime(),
          _p.itemsite_id, _invhistid, TRUE );

      END LOOP;

--  Clear the running detail Qty
      _runningQty := 0;

--  Adjust the detail to the cntslip indicated value
      FOR _cntslip IN SELECT cntslip_location_id, cntslip_lotserial,
                             cntslip_lotserial_expiration,
                             cntslip_lotserial_warrpurc,
                             SUM(cntslip_qty) AS qty,
                             itemsite_item_id
                      FROM cntslip, invcnt, itemsite
                      WHERE ((cntslip_cnttag_id=pInvcntid)
                      AND (cntslip_cnttag_id=invcnt_id)
                      AND (invcnt_itemsite_id=itemsite_id))
                      GROUP BY cntslip_location_id, cntslip_lotserial, 
                      cntslip_lotserial_expiration, cntslip_lotserial_warrpurc,itemsite_item_id LOOP

--  Handle the LotSerial
        IF (LENGTH(_cntslip.cntslip_lotserial)>0) THEN
          SELECT ls_id INTO _lsid
          FROM ls
          WHERE ((ls_item_id=_cntslip.itemsite_item_id)
          AND (UPPER(ls_number)=UPPER(_cntslip.cntslip_lotserial)));

          IF (NOT FOUND) THEN
            _lsid := NEXTVAL('ls_ls_id_seq');
            INSERT INTO ls
            VALUES (_lsid,_cntslip.itemsite_item_id,UPPER(_cntslip.cntslip_lotserial));
          END IF;
        END IF;

--  Track the running Qty
        _runningQty := (_runningQty + _cntslip.qty);
        _hasDetail = TRUE;

--  Create the itemlocdist populating record
        INSERT INTO itemlocdist
        ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
          itemlocdist_itemsite_id,
          itemlocdist_ls_id, itemlocdist_expiration, itemlocdist_warranty,
          itemlocdist_qty, itemlocdist_invhist_id )
        VALUES
        ( _itemlocSeries, 'L', _cntslip.cntslip_location_id,
          _p.itemsite_id,
          _lsid, COALESCE(_cntslip.cntslip_lotserial_expiration, endOfTime()),
          _cntslip.cntslip_lotserial_warrpurc,_cntslip.qty, _invhistid );

      END LOOP;

      IF (_runningQty > _p.invcnt_qoh_after) THEN
--  The total Count Slip Qty is greater than the Count Tag Qty,
--  Don't post the Count.
        _errorCode = -1;

      ELSIF ( (_runningQty < _p.invcnt_qoh_after) AND
              (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and the Item Site is Lot/Serial controlled.
--  Don't post the Count.
        _errorCode = -2;

      ELSIF (_runningQty < _p.invcnt_qoh_after) THEN
        IF ( (NOT _p.itemsite_loccntrl) OR
             (_p.itemsite_location_id = -1) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and there isn't a default location to post into.
--  Don't post the Count.
          _errorCode = -3;

        ELSIF ( SELECT (metric_value='f')
                FROM metric
                WHERE (metric_name='PostCountTagToDefault') ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and we don't post Count Tags to default Locations
--  Don't post the Count.
          _errorCode = -4;

        ELSE
--  Distribute the remaining qty into the default location.
          INSERT INTO itemlocdist
          ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
            itemlocdist_itemsite_id,
            itemlocdist_expiration,
            itemlocdist_qty, itemlocdist_invhist_id )
          SELECT _itemlocSeries, 'L', _p.itemsite_location_id,
                 _p.itemsite_id,
                 endOfTime(),
                 (_p.invcnt_qoh_after - _runningQty), _invhistid;

          _hasDetail = TRUE;
          _errorCode = 0;
        END IF;
      ELSE
--  The Count Slip Qty. must equal the Count Tag Qty.
        _errorCode = 0;
      END IF;

--  If we shouldn't post the count then delete the itemlocdist records,
--  and return with the error.
      IF (_errorCode <> 0) THEN
        DELETE FROM itemlocdist
        WHERE (itemlocdist_series=_itemlocSeries);
  
        RETURN _errorCode;
      END IF;

    END IF;

--  Mod. the Count Tag.
    UPDATE invcnt
    SET invcnt_qoh_before=_p.itemsite_qtyonhand,
        invcnt_postdate=_postDate,
        invcnt_posted=TRUE,
        invcnt_invhist_id=_invhistid,
        invcnt_post_username=getEffectiveXtUser()
    WHERE (invcnt_id=pInvcntid);

--  Create the CC transaction
    INSERT INTO invhist
     ( invhist_id, invhist_itemsite_id,
       invhist_transdate, invhist_transtype, invhist_invqty,
       invhist_qoh_before, invhist_qoh_after,
       invhist_docnumber, invhist_comments,
       invhist_invuom, invhist_unitcost, invhist_hasdetail,
       invhist_costmethod, invhist_value_before, invhist_value_after,
       invhist_series )
    SELECT _invhistid, itemsite_id,
           _postDate, 'CC', (invcnt_qoh_after - invcnt_qoh_before),
           invcnt_qoh_before, invcnt_qoh_after,
           invcnt_tagnumber, invcnt_comments,
           uom_name, _p.cost, _hasDetail,
           _p.itemsite_costmethod, _p.itemsite_value, 
           _p.itemsite_value + (_p.cost * (invcnt_qoh_after - invcnt_qoh_before)),
           _itemlocSeries
    FROM itemsite, invcnt, item, uom
    WHERE ( (invcnt_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (item_inv_uom_id=uom_id)
     AND (itemsite_controlmethod <> 'N')
     AND (invcnt_id=pInvcntid) );

    IF ( SELECT metric_value
        FROM metric
        WHERE ((metric_name = 'EnableAsOfQOH')
        AND (metric_value = 't'))) THEN
      IF (NOT postIntoInvBalance(_invhistid)) THEN
        RAISE EXCEPTION 'Post into Inventory Balance for invhist_id=% was unsuccessful',_invhistid;
      END IF;
    END IF;

--  Update the QOH
--  Avoid negative value when average cost item
    UPDATE itemsite
    SET itemsite_qtyonhand=_p.invcnt_qoh_after,
        itemsite_nnqoh = 0,
        itemsite_value = CASE WHEN ((itemsite_costmethod='A') AND (_p.itemsite_value + (_p.cost * (_p.invcnt_qoh_after - itemsite_qtyonhand))) < 0.0) THEN 0.0
                              ELSE (_p.itemsite_value + (_p.cost * (_p.invcnt_qoh_after - itemsite_qtyonhand)))
                         END,
        itemsite_datelastcount=_postDate
    WHERE (itemsite_id=_p.itemsite_id);
 
--  Post the detail, if any
    IF (_hasDetail) THEN
      PERFORM distributeItemlocSeries(_itemlocSeries);
    END IF;

--  Thaw the itemsite if it's frozen
    IF (pThaw) THEN
      PERFORM thawItemSite(invcnt_itemsite_id) 
      FROM invcnt
      WHERE (invcnt_id=pInvcntid);
    END IF;

--  Distribute to G/L
    PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber, ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
                                 costcat_adjustment_accnt_id, costcat_asset_accnt_id, _invhistid,
                                 ( (_p.invcnt_qoh_after - _p.itemsite_qtyonhand) * _p.cost), _postDate::DATE )
    FROM invcnt, itemsite, costcat
    WHERE ( (invcnt_itemsite_id=itemsite_id)
     AND (itemsite_costcat_id=costcat_id)
     AND (invcnt_id=pInvcntid) );

    RETURN 0;

  ELSE
    RETURN -9;
  END IF;

END;

Function: public.postcounttaglocation(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcntid ALIAS FOR $1;
  pThaw ALIAS FOR $2;
  _avgCostingMethod TEXT;
  _invhistid INTEGER;
  _postDate TIMESTAMP;
  _runningQty NUMERIC;
  _errorCode INTEGER;
  _itemlocSeries INTEGER := 0;
  _hasDetail BOOLEAN;
  _p RECORD;
  _itemloc RECORD;
  _cntslip RECORD;
  _origLocQty NUMERIC;
  _netable BOOLEAN;
  _lsid INTEGER;
BEGIN

  SELECT COALESCE(fetchMetricText('CountAvgCostMethod'), 'STD') INTO _avgCostingMethod;

  SELECT invcnt_id, invcnt_tagnumber, invcnt_qoh_after,
         invcnt_location_id, invcnt_tagdate,
         item_number,
         itemsite_id, itemsite_freeze,
         itemsite_qtyonhand,
         itemsite_loccntrl, COALESCE(invcnt_location_id, -1) AS itemsite_location_id,
         CASE WHEN (itemsite_costmethod = 'N') THEN 0
              WHEN ( (itemsite_costmethod = 'A') AND
                     (itemsite_qtyonhand = 0) AND
                     (_avgCostingMethod = 'ACT') ) THEN actcost(itemsite_item_id)
              WHEN ( (itemsite_costmethod = 'A') AND
                     (_avgCostingMethod IN ('ACT', 'AVG')) ) THEN avgcost(itemsite_id)
              ELSE stdcost(itemsite_item_id)
         END AS cost, itemsite_costmethod,
         itemsite_controlmethod, itemsite_value INTO _p
  FROM invcnt, itemsite, item
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (invcnt_qoh_after IS NOT NULL)
   AND (NOT invcnt_posted)
   AND (invcnt_id=pInvcntid) );
  IF (NOT FOUND) THEN
    RETURN -9;
  END IF;

  SELECT COALESCE(SUM(itemloc_qty),0.0), location_netable INTO _origLocQty,_netable
    FROM itemloc,location
   WHERE ((itemloc_itemsite_id=_p.itemsite_id)
     AND  (location_id=itemloc_location_id)
     AND  (itemloc_location_id=_p.invcnt_location_id))
   GROUP BY location_netable;
  IF (NOT FOUND) THEN
    _origLocQty := 0.0;
    _netable := TRUE;
  END IF;

  SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;

  IF (_p.itemsite_freeze) THEN
    _postDate := _p.invcnt_tagdate;
  ELSE
    _postDate := CURRENT_TIMESTAMP;
  END IF;

  _hasDetail = FALSE;

--  Post the detail indicated by cntslips
  IF ( (_p.itemsite_loccntrl) OR
       (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN

    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;

--  Adjust any existing detail to 0
    FOR _itemloc IN SELECT itemloc_id, itemloc_location_id,
                           itemloc_ls_id, itemloc_qty
                    FROM itemloc
                    WHERE ((itemloc_itemsite_id=_p.itemsite_id)
                      AND  (itemloc_location_id=_p.invcnt_location_id)) LOOP

      _hasDetail = TRUE;

--  Create the itemlocdist flushing records
      INSERT INTO itemlocdist
      ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
        itemlocdist_expiration,
        itemlocdist_itemsite_id, itemlocdist_invhist_id, itemlocdist_flush )
      VALUES
      ( _itemlocSeries, 'I', _itemloc.itemloc_id,
        endOfTime(),
        _p.itemsite_id, _invhistid, TRUE );

    END LOOP;

--  Clear the running detail Qty
    _runningQty := 0;

--  Adjust the detail to the cntslip indicated value
    FOR _cntslip IN SELECT cntslip_location_id, cntslip_lotserial,
                           cntslip_lotserial_expiration,
                           cntslip_lotserial_warrpurc,
                           SUM(cntslip_qty) AS qty,
                           itemsite_item_id
                    FROM cntslip,invcnt,itemsite
                    WHERE ((cntslip_cnttag_id=pInvcntid)
                    AND (cntslip_cnttag_id=invcnt_id)
                    AND (invcnt_itemsite_id=itemsite_id))
                    GROUP BY cntslip_location_id, cntslip_lotserial, cntslip_lotserial_expiration,
                    cntslip_lotserial_warrpurc, itemsite_item_id LOOP

--  Handle the LotSerial
      IF (LENGTH(_cntslip.cntslip_lotserial)>0) THEN
        SELECT ls_id INTO _lsid
        FROM ls
        WHERE ((ls_item_id=_cntslip.itemsite_item_id)
        AND (UPPER(ls_number)=UPPER(_cntslip.cntslip_lotserial)));

        IF (NOT FOUND) THEN
          _lsid := NEXTVAL('ls_ls_id_seq');
          INSERT INTO ls
          VALUES (_lsid,_cntslip.itemsite_item_id,UPPER(_cntslip.cntslip_lotserial));
        END IF;
      END IF;
       
--  Track the running Qty
      _runningQty := (_runningQty + _cntslip.qty);
      _hasDetail = TRUE;

--  Create the itemlocdist populating record
      INSERT INTO itemlocdist
      ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
        itemlocdist_itemsite_id,
        itemlocdist_ls_id, itemlocdist_expiration, itemlocdist_warranty,
        itemlocdist_qty, itemlocdist_invhist_id )
      VALUES
      ( _itemlocSeries, 'L', _cntslip.cntslip_location_id,
        _p.itemsite_id,
        _lsid, COALESCE(_cntslip.cntslip_lotserial_expiration, endOfTime()),
        _cntslip.cntslip_lotserial_warrpurc,
        _cntslip.qty, _invhistid );

    END LOOP;

    IF (_runningQty > _p.invcnt_qoh_after) THEN
--  The total Count Slip Qty is greater than the Count Tag Qty,
--  Don't post the Count.
      _errorCode = -1;

    ELSIF ( (_runningQty < _p.invcnt_qoh_after) AND
            (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and the Item Site is Lot/Serial controlled.
--  Don't post the Count.
      _errorCode = -2;

    ELSIF (_runningQty < _p.invcnt_qoh_after) THEN
      IF ( (NOT _p.itemsite_loccntrl) OR
           (_p.itemsite_location_id = -1) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and there isn't a default location to post into.
--  Don't post the Count.
        _errorCode = -3;

      ELSIF ( SELECT (metric_value='f')
              FROM metric
              WHERE (metric_name='PostCountTagToDefault') ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and we don't post Count Tags to default Locations
--  Don't post the Count.
        _errorCode = -4;

      ELSE
--  Distribute the remaining qty into the default location.
        INSERT INTO itemlocdist
        ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
          itemlocdist_itemsite_id,
          itemlocdist_ls_id, itemlocdist_expiration,
          itemlocdist_qty, itemlocdist_invhist_id )
        SELECT _itemlocSeries, 'L', _p.itemsite_location_id,
               _p.itemsite_id,
               _lsid, endOfTime(),
               (_p.invcnt_qoh_after - _runningQty), _invhistid;

        _hasDetail = TRUE;
        _errorCode = 0;
      END IF;
    ELSE
--  The Count Slip Qty. must equal the Count Tag Qty.
      _errorCode = 0;
    END IF;

--  If we shouldn't post the count then delete the itemlocdist records,
--  and return with the error.
    IF (_errorCode <> 0) THEN
      DELETE FROM itemlocdist
      WHERE (itemlocdist_series=_itemlocSeries);
  
      RETURN _errorCode;
    END IF;

  END IF;

--  Mod. the Count Tag.
  UPDATE invcnt
  SET invcnt_qoh_before=_origLocQty,
      invcnt_postdate=_postDate,
      invcnt_posted=TRUE,
      invcnt_invhist_id=_invhistid,
      invcnt_post_username=getEffectiveXtUser()
  WHERE (invcnt_id=pInvcntid);

--  Create the CC transaction
  INSERT INTO invhist
   ( invhist_id, invhist_itemsite_id,
     invhist_transdate, invhist_transtype, invhist_invqty,
     invhist_qoh_before, invhist_qoh_after,
     invhist_docnumber, invhist_comments,
     invhist_invuom, invhist_unitcost, invhist_hasdetail,
     invhist_costmethod, invhist_value_before, invhist_value_after,
     invhist_series )
  SELECT _invhistid, itemsite_id,
         _postDate, 'CC', (invcnt_qoh_after - invcnt_qoh_before),
         invcnt_qoh_before, invcnt_qoh_after,
         invcnt_tagnumber, invcnt_comments,
         uom_name, _p.cost, _hasDetail,
         _p.itemsite_costmethod, _p.itemsite_value,
         _p.itemsite_value + (_p.cost * (invcnt_qoh_after - invcnt_qoh_before)),
         _itemlocSeries
  FROM itemsite, invcnt, item, uom
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (item_inv_uom_id=uom_id)
   AND (itemsite_controlmethod <> 'N')
   AND (invcnt_id=pInvcntid) );

--  Update the QOH
  IF (_netable) THEN
    UPDATE itemsite
    SET itemsite_qtyonhand= itemsite_qtyonhand + (_p.invcnt_qoh_after - _origLocQty),
        itemsite_datelastcount=_postDate
    WHERE (itemsite_id=_p.itemsite_id);
  ELSE
    UPDATE itemsite
    SET itemsite_nnqoh =  itemsite_nnqoh - _origLocQty,
	itemsite_qtyonhand = itemsite_qtyonhand + _p.invcnt_qoh_after,
        itemsite_datelastcount=_postDate
    WHERE (itemsite_id=_p.itemsite_id);
  END IF;
 
--  Post the detail, if any
  IF (_hasDetail) THEN
    PERFORM distributeItemlocSeries(_itemlocSeries);
  END IF;

--  Thaw the itemsite if it's frozen
  IF (pThaw) THEN
    PERFORM thawItemSite(invcnt_itemsite_id) 
    FROM invcnt
    WHERE (invcnt_id=pInvcntid);
  END IF;

--  Distribute to G/L
  PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber, ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
                               costcat_adjustment_accnt_id, costcat_asset_accnt_id, _invhistid,
                               ( (_p.invcnt_qoh_after - _origLocQty) * _p.cost), CURRENT_DATE )
  FROM invcnt, itemsite, costcat
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (invcnt_id=pInvcntid) );

  RETURN 0;
END;

Function: public.postcounttaglocation(integer, boolean, text)

Returns: integer

Language: PLPGSQL

DECLARE
  pInvcntid ALIAS FOR $1;
  pThaw ALIAS FOR $2;
  pAvgCostingMethod ALIAS FOR $3;
  _invhistid INTEGER;
  _postDate TIMESTAMP;
  _runningQty NUMERIC;
  _errorCode INTEGER;
  _itemlocSeries INTEGER := 0;
  _hasDetail BOOLEAN;
  _p RECORD;
  _itemloc RECORD;
  _cntslip RECORD;
  _origLocQty NUMERIC;
  _netable BOOLEAN;
  _lsid INTEGER;
BEGIN

  SELECT invcnt_id, invcnt_tagnumber, invcnt_qoh_after,
         invcnt_location_id, invcnt_tagdate,
         item_number,
         itemsite_id, itemsite_freeze,
         itemsite_qtyonhand,
         itemsite_loccntrl, COALESCE(invcnt_location_id, -1) AS itemsite_location_id,
         CASE WHEN (itemsite_costmethod = 'N') THEN 0
              WHEN ( (itemsite_costmethod = 'A') AND
                     (itemsite_qtyonhand = 0) AND
                     (pAvgCostingMethod = 'ACT') ) THEN actcost(itemsite_item_id)
              WHEN ( (itemsite_costmethod = 'A') AND
                     (pAvgCostingMethod IN ('ACT', 'AVG')) ) THEN avgcost(itemsite_id)
              ELSE stdcost(itemsite_item_id)
         END AS cost, itemsite_costmethod,
         itemsite_controlmethod, itemsite_value INTO _p
  FROM invcnt, itemsite, item
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (invcnt_qoh_after IS NOT NULL)
   AND (NOT invcnt_posted)
   AND (invcnt_id=pInvcntid) );
  IF (NOT FOUND) THEN
    RETURN -9;
  END IF;

  SELECT COALESCE(SUM(itemloc_qty),0.0), location_netable INTO _origLocQty,_netable
    FROM itemloc,location
   WHERE ((itemloc_itemsite_id=_p.itemsite_id)
     AND  (location_id=itemloc_location_id)
     AND  (itemloc_location_id=_p.invcnt_location_id))
   GROUP BY location_netable;
  IF (NOT FOUND) THEN
    _origLocQty := 0.0;
    _netable := TRUE;
  END IF;

  SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;

  IF (_p.itemsite_freeze) THEN
    _postDate := _p.invcnt_tagdate;
  ELSE
    _postDate := CURRENT_TIMESTAMP;
  END IF;

  _hasDetail = FALSE;

--  Post the detail indicated by cntslips
  IF ( (_p.itemsite_loccntrl) OR
       (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN

    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;

--  Adjust any existing detail to 0
    FOR _itemloc IN SELECT itemloc_id, itemloc_location_id,
                           itemloc_ls_id, itemloc_qty
                    FROM itemloc
                    WHERE ((itemloc_itemsite_id=_p.itemsite_id)
                      AND  (itemloc_location_id=_p.invcnt_location_id)) LOOP

      _hasDetail = TRUE;

--  Create the itemlocdist flushing records
      INSERT INTO itemlocdist
      ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
        itemlocdist_expiration,
        itemlocdist_itemsite_id, itemlocdist_invhist_id, itemlocdist_flush )
      VALUES
      ( _itemlocSeries, 'I', _itemloc.itemloc_id,
        endOfTime(),
        _p.itemsite_id, _invhistid, TRUE );

    END LOOP;

--  Clear the running detail Qty
    _runningQty := 0;

--  Adjust the detail to the cntslip indicated value
    FOR _cntslip IN SELECT cntslip_location_id, cntslip_lotserial,
                           cntslip_lotserial_expiration,
                           cntslip_lotserial_warrpurc,
                           SUM(cntslip_qty) AS qty,
                           itemsite_item_id
                    FROM cntslip,invcnt,itemsite
                    WHERE ((cntslip_cnttag_id=pInvcntid)
                    AND (cntslip_cnttag_id=invcnt_id)
                    AND (invcnt_itemsite_id=itemsite_id))
                    GROUP BY cntslip_location_id, cntslip_lotserial, cntslip_lotserial_expiration,
                    cntslip_lotserial_warrpurc, itemsite_item_id LOOP

--  Handle the LotSerial
      IF (LENGTH(_cntslip.cntslip_lotserial)>0) THEN
        SELECT ls_id INTO _lsid
        FROM ls
        WHERE ((ls_item_id=_cntslip.itemsite_item_id)
        AND (UPPER(ls_number)=UPPER(_cntslip.cntslip_lotserial)));

        IF (NOT FOUND) THEN
          _lsid := NEXTVAL('ls_ls_id_seq');
          INSERT INTO ls
          VALUES (_lsid,_cntslip.itemsite_item_id,UPPER(_cntslip.cntslip_lotserial));
        END IF;
      END IF;
       
--  Track the running Qty
      _runningQty := (_runningQty + _cntslip.qty);
      _hasDetail = TRUE;

--  Create the itemlocdist populating record
      INSERT INTO itemlocdist
      ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
        itemlocdist_itemsite_id,
        itemlocdist_ls_id, itemlocdist_expiration, itemlocdist_warranty,
        itemlocdist_qty, itemlocdist_invhist_id )
      VALUES
      ( _itemlocSeries, 'L', _cntslip.cntslip_location_id,
        _p.itemsite_id,
        _lsid, COALESCE(_cntslip.cntslip_lotserial_expiration, endOfTime()),
        _cntslip.cntslip_lotserial_warrpurc,
        _cntslip.qty, _invhistid );

    END LOOP;

    IF (_runningQty > _p.invcnt_qoh_after) THEN
--  The total Count Slip Qty is greater than the Count Tag Qty,
--  Don't post the Count.
      _errorCode = -1;

    ELSIF ( (_runningQty < _p.invcnt_qoh_after) AND
            (_p.itemsite_controlmethod IN ('L', 'S')) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and the Item Site is Lot/Serial controlled.
--  Don't post the Count.
      _errorCode = -2;

    ELSIF (_runningQty < _p.invcnt_qoh_after) THEN
      IF ( (NOT _p.itemsite_loccntrl) OR
           (_p.itemsite_location_id = -1) ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and there isn't a default location to post into.
--  Don't post the Count.
        _errorCode = -3;

      ELSIF ( SELECT (metric_value='f')
              FROM metric
              WHERE (metric_name='PostCountTagToDefault') ) THEN
--  The total Count Slip Qty is less than the Count Tag Qty,
--  and we don't post Count Tags to default Locations
--  Don't post the Count.
        _errorCode = -4;

      ELSE
--  Distribute the remaining qty into the default location.
        INSERT INTO itemlocdist
        ( itemlocdist_series, itemlocdist_source_type, itemlocdist_source_id,
          itemlocdist_itemsite_id,
          itemlocdist_ls_id, itemlocdist_expiration,
          itemlocdist_qty, itemlocdist_invhist_id )
        SELECT _itemlocSeries, 'L', _p.itemsite_location_id,
               _p.itemsite_id,
               _lsid, endOfTime(),
               (_p.invcnt_qoh_after - _runningQty), _invhistid;

        _hasDetail = TRUE;
        _errorCode = 0;
      END IF;
    ELSE
--  The Count Slip Qty. must equal the Count Tag Qty.
      _errorCode = 0;
    END IF;

--  If we shouldn't post the count then delete the itemlocdist records,
--  and return with the error.
    IF (_errorCode <> 0) THEN
      DELETE FROM itemlocdist
      WHERE (itemlocdist_series=_itemlocSeries);
  
      RETURN _errorCode;
    END IF;

  END IF;

--  Mod. the Count Tag.
  UPDATE invcnt
  SET invcnt_qoh_before=_origLocQty,
      invcnt_postdate=_postDate,
      invcnt_posted=TRUE,
      invcnt_invhist_id=_invhistid,
      invcnt_post_username=CURRENT_USER
  WHERE (invcnt_id=pInvcntid);

--  Create the CC transaction
  INSERT INTO invhist
   ( invhist_id, invhist_itemsite_id,
     invhist_transdate, invhist_transtype, invhist_invqty,
     invhist_qoh_before, invhist_qoh_after,
     invhist_docnumber, invhist_comments,
     invhist_invuom, invhist_unitcost, invhist_hasdetail,
     invhist_costmethod, invhist_value_before, invhist_value_after,
     invhist_series )
  SELECT _invhistid, itemsite_id,
         _postDate, 'CC', (invcnt_qoh_after - invcnt_qoh_before),
         invcnt_qoh_before, invcnt_qoh_after,
         invcnt_tagnumber, invcnt_comments,
         uom_name, _p.cost, _hasDetail,
         _p.itemsite_costmethod, _p.itemsite_value,
         _p.itemsite_value + (_p.cost * (invcnt_qoh_after - invcnt_qoh_before)),
         _itemlocSeries
  FROM itemsite, invcnt, item, uom
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (item_inv_uom_id=uom_id)
   AND (itemsite_controlmethod <> 'N')
   AND (invcnt_id=pInvcntid) );

--  Update the QOH
  IF (_netable) THEN
    UPDATE itemsite
    SET itemsite_qtyonhand= itemsite_qtyonhand + (_p.invcnt_qoh_after - _origLocQty),
        itemsite_datelastcount=_postDate
    WHERE (itemsite_id=_p.itemsite_id);
  ELSE
    UPDATE itemsite
    SET itemsite_nnqoh =  itemsite_nnqoh - _origLocQty,
	itemsite_qtyonhand = itemsite_qtyonhand + _p.invcnt_qoh_after,
        itemsite_datelastcount=_postDate
    WHERE (itemsite_id=_p.itemsite_id);
  END IF;
 
--  Post the detail, if any
  IF (_hasDetail) THEN
    PERFORM distributeItemlocSeries(_itemlocSeries);
  END IF;

--  Thaw the itemsite if it's frozen
  IF (pThaw) THEN
    PERFORM thawItemSite(invcnt_itemsite_id) 
    FROM invcnt
    WHERE (invcnt_id=pInvcntid);
  END IF;

--  Distribute to G/L
  PERFORM insertGLTransaction( 'I/M', 'CT', _p.invcnt_tagnumber, ('Post Count Tag #' || _p.invcnt_tagnumber || ' for Item ' || _p.item_number),
                               costcat_adjustment_accnt_id, costcat_asset_accnt_id, _invhistid,
                               ( (_p.invcnt_qoh_after - _origLocQty) * _p.cost), CURRENT_DATE )
  FROM invcnt, itemsite, costcat
  WHERE ( (invcnt_itemsite_id=itemsite_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (invcnt_id=pInvcntid) );

  RETURN 0;
END;

Function: public.postcounttags(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pThaw ALIAS FOR $2;
  _invcnt RECORD;
  _result INTEGER := 0;
  _return INTEGER := 0;

BEGIN

  FOR _invcnt IN SELECT invcnt_id
                 FROM invcnt, itemsite
                 WHERE ( (invcnt_itemsite_id=itemsite_id)
                  AND ( (pWarehousid=-1) OR (itemsite_warehous_id=pWarehousid) )
                  AND (invcnt_qoh_after IS NOT NULL)
                  AND (NOT invcnt_posted) ) LOOP
    SELECT postCountTag(_invcnt.invcnt_id, pThaw) INTO _result;
    IF (_result < _return) THEN
      _return := _result;
    END IF;
  END LOOP;

  RETURN _return;

END;

Function: public.postcreditmemo(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  pItemlocSeries ALIAS FOR $2;
  _return INTEGER;

BEGIN

  SELECT postCreditMemo(pCmheadid, fetchJournalNumber('AR-CM'), pItemlocSeries) INTO _return;

  RETURN _return;

END;

Function: public.postcreditmemo(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  _r RECORD;
  _p RECORD;
  _aropenid INTEGER;
  _cohistid INTEGER;
  _sequence INTEGER;
  _itemlocSeries INTEGER;
  _invhistid INTEGER;
  _test INTEGER;
  _totalAmount NUMERIC   := 0;
  _commissionDue NUMERIC := 0;
  _toApply NUMERIC;
  _toClose BOOLEAN;
  _glDate	DATE;
  _taxBaseValue	NUMERIC	:= 0;

BEGIN

--  Cache some parameters
  SELECT cmhead.*,
         findARAccount(cmhead_cust_id) AS ar_accnt_id,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM cmheadtax
           WHERE ( (taxhist_parent_id = cmhead_id)
             AND   (taxhist_taxtype_id = getAdjustmentTaxtypeId()) ) ) AS adjtax
         INTO _p
  FROM cmhead
  WHERE (cmhead_id=pCmheadid);

  IF (_p.cmhead_posted) THEN
    RETURN -10;
  END IF;

  IF (_p.cmhead_hold) THEN
    RETURN -11;
  END IF;

  _glDate := COALESCE(_p.cmhead_gldistdate, _p.cmhead_docdate);

  _itemlocSeries = pItemlocSeries;

  SELECT fetchGLSequence() INTO _sequence;

--  Start by handling taxes
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.cmhead_curr_id, round(sum(taxdetail_tax),2), _p.cmhead_docdate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('CM', pCmheadid, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CM', _p.cmhead_number,
                                _r.tax_sales_accnt_id, 
                                _r.taxbasevalue,
                                _glDate, _p.cmhead_billtoname );

    _totalAmount := _totalAmount + _r.tax * -1;
  END LOOP;

-- Update item tax records with posting data
  UPDATE cmitemtax SET 
    taxhist_docdate=_p.cmhead_docdate,
    taxhist_distdate=_glDate,
    taxhist_curr_id=_p.cmhead_curr_id,
    taxhist_curr_rate=curr_rate,
    taxhist_journalnumber=pJournalNumber
  FROM cmhead
   JOIN cmitem ON (cmhead_id=cmitem_cmhead_id),
   curr_rate
  WHERE ((cmhead_id=pCmheadId)
    AND (taxhist_parent_id=cmitem_id)
    AND (_p.cmhead_curr_id=curr_id)
    AND (_p.cmhead_docdate BETWEEN curr_effective 
                           AND curr_expires) );

-- Update Header taxes (Freight and Adjustments) with posting data
  UPDATE cmheadtax SET 
    taxhist_docdate=_p.cmhead_docdate,
    taxhist_distdate=_glDate,
    taxhist_curr_id=_p.cmhead_curr_id,
    taxhist_curr_rate=curr_rate,
    taxhist_journalnumber=pJournalNumber
  FROM curr_rate
  WHERE ((taxhist_parent_id=pCmheadId)
    AND (_p.cmhead_curr_id=curr_id)
    AND (_p.cmhead_docdate BETWEEN curr_effective 
                           AND curr_expires) );

-- Process line items
-- Always use std cost
  FOR _r IN SELECT *, stdCost(item_id) AS std_cost
            FROM creditmemoitem
            WHERE ( (cmitem_cmhead_id=pCmheadid)
              AND   (cmitem_qtycredit <> 0 ) ) LOOP

--  Calcuate the Commission to be debited
    _commissionDue := (_commissionDue + (_r.extprice * _p.cmhead_commission));

    IF (_r.extprice <> 0) THEN
--  Debit the Sales Account for the current cmitem
      SELECT insertIntoGLSeries( _sequence, 'A/R', 'CM', _p.cmhead_number,
                                 CASE WHEN _p.cmhead_rahead_id IS NULL THEN
                                   getPrjAccntId(_p.cmhead_prj_id, salesaccnt_credit_accnt_id)
                                 ELSE
                                   getPrjAccntId(_p.cmhead_prj_id, salesaccnt_returns_accnt_id)
                                 END,
                               round(currToBase(_p.cmhead_curr_id,
                                                _r.extprice * -1,
                                                _p.cmhead_docdate), 2),
                                 _glDate, _p.cmhead_billtoname) INTO _test
      FROM salesaccnt
      WHERE (salesaccnt_id=findSalesAccnt(_r.cmitem_itemsite_id, 'IS', _p.cmhead_cust_id,
                                          _p.cmhead_saletype_id, _p.cmhead_shipzone_id));
      IF (NOT FOUND) THEN
        PERFORM deleteGLSeries(_sequence);
        RETURN -12;
      END IF;
    END IF;

--  Record Sales History for this C/M Item
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.cmhead_cust_id, _r.cmitem_itemsite_id, _p.cmhead_shipto_id,
      _p.cmhead_docdate, '',
      _p.cmhead_number, _p.cmhead_custponumber, _p.cmhead_docdate,
      'C', _p.cmhead_invcnumber, _p.cmhead_docdate,
      (_r.qty * -1), _r.unitprice, _r.std_cost,
      _p.cmhead_salesrep_id, (_p.cmhead_commission * _r.extprice * -1), FALSE,
      _p.cmhead_billtoname, _p.cmhead_billtoaddress1,
      _p.cmhead_billtoaddress2, _p.cmhead_billtoaddress3,
      _p.cmhead_billtocity, _p.cmhead_billtostate, _p.cmhead_billtozip,
      _p.cmhead_shipto_name, _p.cmhead_shipto_address1,
      _p.cmhead_shipto_address2, _p.cmhead_shipto_address3,
      _p.cmhead_shipto_city, _p.cmhead_shipto_state, _p.cmhead_shipto_zipcode,
      _p.cmhead_curr_id, _r.cmitem_taxtype_id, _p.cmhead_taxzone_id,
      _p.cmhead_shipzone_id, _p.cmhead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber 
    FROM cmitemtax
    WHERE (taxhist_parent_id=_r.cmitem_id);

    _totalAmount := _totalAmount + round(_r.extprice, 2);

  END LOOP;

--  Credit the Misc. Account for Miscellaneous Charges
  IF (_p.cmhead_misc <> 0) THEN
    SELECT insertIntoGLSeries( _sequence, 'A/R', 'CM', _p.cmhead_number,
                               getPrjAccntId(_p.cmhead_prj_id, accnt_id), round(currToBase(_p.cmhead_curr_id,
                                                          _p.cmhead_misc * -1,
                                                          _p.cmhead_docdate), 2),
                               _glDate, _p.cmhead_billtoname) INTO _test
    FROM accnt
    WHERE (accnt_id=_p.cmhead_misc_accnt_id);

--  If the Misc. Charges Account was not found then punt
    IF (NOT FOUND) THEN
      PERFORM deleteGLSeries(_sequence);
      RETURN -14;
    END IF;

--  Record the Sales History for any Misc. Charge
    INSERT INTO cohist
    ( cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip, cohist_misc_id,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _p.cmhead_cust_id, -1, _p.cmhead_shipto_id,
      'M', _p.cmhead_misc_descrip, _p.cmhead_misc_accnt_id,
      _p.cmhead_docdate, '',
      _p.cmhead_number, _p.cmhead_custponumber, _p.cmhead_docdate,
      'C', _p.cmhead_invcnumber, _p.cmhead_docdate,
      1, (_p.cmhead_misc * -1), (_p.cmhead_misc * -1),
      _p.cmhead_salesrep_id, 0, FALSE,
      _p.cmhead_billtoname, _p.cmhead_billtoaddress1,
      _p.cmhead_billtoaddress2, _p.cmhead_billtoaddress3,
      _p.cmhead_billtocity, _p.cmhead_billtostate, _p.cmhead_billtozip,
      _p.cmhead_shipto_name, _p.cmhead_shipto_address1,
      _p.cmhead_shipto_address2, _p.cmhead_shipto_address3,
      _p.cmhead_shipto_city, _p.cmhead_shipto_state, _p.cmhead_shipto_zipcode,
      _p.cmhead_curr_id,
      _p.cmhead_shipzone_id, _p.cmhead_saletype_id );

--  Cache the Misc. Amount distributed
    _totalAmount := _totalAmount + _p.cmhead_misc;
  END IF;

  -- Credit Tax Adjustments
  IF (_p.adjtax <> 0) THEN
  --  Record the Sales History for Tax Adjustment
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.cmhead_cust_id, -1, _p.cmhead_shipto_id,
      'T', 'Misc Tax Adjustment',
      _p.cmhead_docdate, '',
      _p.cmhead_number, _p.cmhead_custponumber, _p.cmhead_docdate,
      'C', _p.cmhead_invcnumber, _p.cmhead_docdate,
      0, 0, 0,
      _p.cmhead_salesrep_id, 0, FALSE,
      _p.cmhead_billtoname, _p.cmhead_billtoaddress1,
      _p.cmhead_billtoaddress2, _p.cmhead_billtoaddress3,
      _p.cmhead_billtocity, _p.cmhead_billtostate, _p.cmhead_billtozip,
      _p.cmhead_shipto_name, _p.cmhead_shipto_address1,
      _p.cmhead_shipto_address2, _p.cmhead_shipto_address3,
      _p.cmhead_shipto_city, _p.cmhead_shipto_state, _p.cmhead_shipto_zipcode,
      _p.cmhead_curr_id, getAdjustmentTaxtypeId(), _p.cmhead_taxzone_id,
      _p.cmhead_shipzone_id, _p.cmhead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber  )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           (taxhist_basis * -1), taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber 
    FROM cmheadtax
    WHERE ( (taxhist_parent_id=_p.cmhead_id)
      AND   (taxhist_taxtype_id=getAdjustmentTaxtypeId()) );

  END IF;

--  Debit the Freight Account
  IF (_p.cmhead_freight <> 0) THEN
    SELECT insertIntoGLSeries( _sequence, 'A/R', 'CM', _p.cmhead_number,
                               getPrjAccntId(_p.cmhead_prj_id, accnt_id),
                               round(currToBase(_p.cmhead_curr_id,
                                                _p.cmhead_freight * -1,
                                                _p.cmhead_docdate), 2),
                               _glDate, _p.cmhead_billtoname) INTO _test
    FROM accnt
    WHERE (accnt_id=findFreightAccount(_p.cmhead_cust_id));

--  If the Freight Charges Account was not found then punt
    IF (NOT FOUND) THEN
      PERFORM deleteGLSeries(_sequence);
      RETURN -16;
    END IF;

--  Cache the Amount Distributed to Freight
    _totalAmount := _totalAmount + _p.cmhead_freight;

--  Record the Sales History for any Freight
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.cmhead_cust_id, -1, _p.cmhead_shipto_id,
      'F', 'Freight Charge',
      _p.cmhead_docdate, '',
      _p.cmhead_number, _p.cmhead_custponumber, _p.cmhead_docdate,
      'C', _p.cmhead_invcnumber, _p.cmhead_docdate,
      1, (_p.cmhead_freight * -1), (_p.cmhead_freight * -1),
      _p.cmhead_salesrep_id, 0, FALSE,
      _p.cmhead_billtoname, _p.cmhead_billtoaddress1,
      _p.cmhead_billtoaddress2, _p.cmhead_billtoaddress3,
      _p.cmhead_billtocity, _p.cmhead_billtostate, _p.cmhead_billtozip,
      _p.cmhead_shipto_name, _p.cmhead_shipto_address1,
      _p.cmhead_shipto_address2, _p.cmhead_shipto_address3,
      _p.cmhead_shipto_city, _p.cmhead_shipto_state, _p.cmhead_shipto_zipcode,
      _p.cmhead_curr_id, getFreightTaxtypeId(), _p.cmhead_taxzone_id,
      _p.cmhead_shipzone_id, _p.cmhead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber  )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           (taxhist_basis * -1), taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber 
    FROM cmheadtax
    WHERE ( (taxhist_parent_id=_p.cmhead_id)
      AND   (taxhist_taxtype_id=getFreightTaxtypeId()) );

  END IF;

  _totalAmount := _totalAmount;

--  Credit the A/R for the total Amount
  IF (_totalAmount <> 0) THEN
    IF (_p.ar_accnt_id != -1) THEN
      PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CM', _p.cmhead_number,
                                  _p.ar_accnt_id,
                                  round(currToBase(_p.cmhead_curr_id,
                                                   _totalAmount,
                                                   _p.cmhead_docdate), 2),
                                  _glDate, _p.cmhead_billtoname);
    ELSE
      PERFORM deleteGLSeries(_sequence);
      RETURN -18;
    END IF;
  END IF;

--  Commit the GLSeries;
  PERFORM postGLSeries(_sequence, pJournalNumber);

--  Create the Invoice aropen item
  SELECT NEXTVAL('aropen_aropen_id_seq') INTO _aropenid;
  INSERT INTO aropen
  ( aropen_id, aropen_username, aropen_journalnumber,
    aropen_open, aropen_posted,
    aropen_cust_id, aropen_ponumber,
    aropen_docnumber,
    aropen_applyto, aropen_doctype,
    aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id,
    aropen_amount, aropen_paid,
    aropen_salesrep_id, aropen_commission_due, aropen_commission_paid,
    aropen_ordernumber, aropen_notes,
    aropen_rsncode_id, aropen_curr_id )
  SELECT _aropenid, getEffectiveXtUser(), pJournalNumber,
         TRUE, FALSE,
         cmhead_cust_id, cmhead_custponumber,
         cmhead_number,
         CASE WHEN (cmhead_invcnumber='-1') THEN 'OPEN'
              ELSE (cmhead_invcnumber::TEXT)
         END,
         'C',
         cmhead_docdate, cmhead_docdate, _glDate, -1,
         _totalAmount, 0,
         cmhead_salesrep_id, (_commissionDue * -1), FALSE,
         cmhead_number::TEXT, cmhead_comments,
         cmhead_rsncode_id, cmhead_curr_id
  FROM cmhead
  WHERE (cmhead_id=pCmheadid);

-- Handle the Inventory and G/L Transactions for any returned Inventory where cmitem_updateinv is true
  FOR _r IN SELECT cmitem_itemsite_id AS itemsite_id, cmitem_id,
                   (cmitem_qtyreturned * cmitem_qty_invuomratio) AS qty,
                   cmhead_number, cmhead_cust_id AS cust_id, item_number,
                   cmhead_saletype_id AS saletype_id, cmhead_shipzone_id AS shipzone_id,
                   stdCost(item_id) AS std_cost, cmhead_prj_id,
                   itemsite_costmethod
            FROM cmhead, cmitem, itemsite, item
            WHERE ( (cmitem_cmhead_id=cmhead_id)
             AND (cmitem_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (cmitem_qtyreturned <> 0)
             AND (cmitem_updateinv)
             AND (cmhead_id=pCmheadid) ) LOOP

--  Return credited stock to inventory
    IF (_itemlocSeries = 0) THEN
      _itemlocSeries := NEXTVAL('itemloc_series_seq');
    END IF;
    IF (_r.itemsite_costmethod != 'J') THEN
      SELECT postInvTrans(itemsite_id, 'RS', _r.qty,
                         'S/O', 'CM', _r.cmhead_number, '',
                         ('Credit Return ' || _r.item_number),
                         costcat_asset_accnt_id,
                         getPrjAccntId(_r.cmhead_prj_id, resolveCOSAccount(itemsite_id, _r.cust_id, _r.saletype_id, _r.shipzone_id)), 
                         _itemlocSeries, _glDate, _r.std_cost) INTO _invhistid
        FROM itemsite, costcat
       WHERE ((itemsite_costcat_id=costcat_id)
          AND (itemsite_id=_r.itemsite_id));
    ELSE
      RAISE DEBUG 'postCreditMemo(%, %, %) tried to postInvTrans a %-costed item',
                  pCmheadid, pJournalNumber, pItemlocSeries,
                  _r.itemsite_costmethod;
    END IF;

  END LOOP;

--  Update coitem to reflect the returned qty where cmitem_updateinv is true
  FOR _r IN SELECT cmitem_qtyreturned, cmitem_itemsite_id, cohead_id
            FROM cmitem, cmhead, invchead, cohead
            WHERE ( (cmitem_cmhead_id=cmhead_id)
             AND (cmhead_invcnumber=invchead_invcnumber)
             AND (invchead_ordernumber=cohead_number)
             AND (cmitem_qtyreturned <> 0)
             AND (cmitem_updateinv)
             AND (cmhead_id=pCmheadid) ) LOOP
    UPDATE coitem
    SET coitem_qtyreturned = (coitem_qtyreturned + _r.cmitem_qtyreturned)
    WHERE coitem_id IN ( SELECT coitem_id
                         FROM coitem
                         WHERE ( (coitem_cohead_id=_r.cohead_id)
                          AND (coitem_itemsite_id = _r.cmitem_itemsite_id) )
                         LIMIT 1 );
  END LOOP;

--  Mark the cmhead as posted
  UPDATE cmhead
  SET cmhead_posted=TRUE, cmhead_gldistdate=_glDate
  WHERE (cmhead_id=pCmheadid);

--  Find the apply-to document and make the application
  SELECT cmhead_number, cmhead_curr_id, cmhead_docdate,
         aropen_id, aropen_cust_id, aropen_docnumber,
         currToCurr(aropen_curr_id, cmhead_curr_id, aropen_amount - aropen_paid,
                    cmhead_docdate) AS balance INTO _p
  FROM aropen, cmhead
  WHERE ( (aropen_doctype='I')
   AND (aropen_docnumber=cmhead_invcnumber)
   AND (cmhead_id=pCmheadid) );
  IF (FOUND) THEN

    IF round(_totalAmount, 2) <= round(_p.balance, 2) THEN
      _toApply = _totalAmount;
    ELSE
      _toApply = _p.balance;
    END IF;

    UPDATE aropen
    SET aropen_paid = round(aropen_paid + currToCurr(_p.cmhead_curr_id,
                                                     aropen_curr_id, _toApply,
                                                     _p.cmhead_docdate), 2)
    WHERE (aropen_id=_p.aropen_id);

--  Alter the new A/R Open Item to reflect the application
    UPDATE aropen
    SET aropen_paid = round(currToCurr(_p.cmhead_curr_id, aropen_curr_id,
                                       _toApply, _p.cmhead_docdate), 2)
    WHERE (aropen_id=_aropenid);

--  Record the application
    INSERT INTO arapply
    ( arapply_cust_id,
      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
      arapply_fundstype, arapply_refnumber,
      arapply_applied, arapply_closed,
      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_curr_id )
    VALUES
    ( _p.aropen_cust_id,
      _aropenid, 'C', _p.cmhead_number,
      _p.aropen_id, 'I', _p.aropen_docnumber,
      '', '',
      round(_toApply, 2), _toClose,
      CURRENT_DATE, _p.cmhead_docdate, 0, _p.cmhead_curr_id );

  END IF;
    
  RETURN _itemlocSeries;

END;

Function: public.postcreditmemos(boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostUnprinted ALIAS FOR $1;
  _cmhead RECORD;
  _result INTEGER;
  _return INTEGER        := 0;
  _itemlocSeries INTEGER := 0;

BEGIN

  _itemlocSeries := 0;

  FOR _cmhead IN SELECT cmhead_id
                 FROM cmhead
                 WHERE ( (NOT cmhead_posted)
                   AND   (NOT cmhead_hold)
                   AND   (checkCreditMemoSitePrivs(cmhead_id))
                   AND   ((pPostUnprinted) OR (cmhead_printed)) ) LOOP

    SELECT postCreditMemo(_cmhead.cmhead_id, _itemlocSeries) INTO _result;
    IF (_result < _return) THEN
      _return := _result;
    END IF;

  END LOOP;

  RETURN _return;

END;

Function: public.postcreditmemos(boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostUnprinted ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _r RECORD;
  _itemlocSeries INTEGER := 0;

BEGIN

  _itemlocSeries := 0;

  FOR _r IN SELECT cmhead_id
            FROM cmhead
            WHERE ( (NOT cmhead_posted)
              AND   (NOT cmhead_hold)
              AND   (checkCreditMemoSitePrivs(cmhead_id))
              AND   ((pPostUnprinted) OR (cmhead_printed)) ) LOOP

    SELECT postCreditMemo(_r.cmhead_id, pJournalNumber, _itemlocSeries) INTO _itemlocSeries;

  END LOOP;

  RETURN _itemlocSeries;

END;

Function: public.postglseries(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  _journalNumber INTEGER;
  _returnValue INTEGER;

BEGIN

  SELECT postGLSeries(pSequence, fetchJournalNumber('G/L')) INTO _returnValue;
  RETURN _returnValue;

END;

Function: public.postglseries(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _returnValue INTEGER;

BEGIN

  SELECT postGLSeries(pSequence, pJournalNumber, true) INTO _returnValue;
  RETURN _returnValue;

END;

Function: public.postglseries(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence 		ALIAS FOR $1;
  pJournalNumber 	ALIAS FOR $2;
  pPostZero		ALIAS FOR $3;
  _glseries RECORD;
  _transCount INTEGER := 0;
  _delta NUMERIC;
  _discrepDate DATE;
  _discrepAccntid INTEGER;
  _rows INTEGER;
BEGIN

/*  Make sure we don't create an imbalance across companies.
    The 'IgnoreCompanyBalance' metric is a back door mechanism to
    allow legacy users to create transactions accross companies if
    they have been using the company segment for something else
    and they MUST continue to be able to do so.  It can only be 
    implemented by direct sql update to the metric table and should 
    otherwise be discouraged.
*/ 
  IF (COALESCE(fetchMetricValue('GLCompanySize'),0) > 0 
    AND fetchMetricBool('IgnoreCompany') = false)  THEN

    SELECT count(accnt_company) INTO _rows
    FROM (
      SELECT DISTINCT accnt_company
      FROM accnt 
        JOIN glseries ON (glseries_accnt_id=accnt_id)
      WHERE (glseries_sequence=pSequence)) _data;
    
    IF (_rows > 1) THEN
      RAISE EXCEPTION 'G/L Series can not be posted because multiple companies are referenced in the same series.';
    END IF;
  END IF;
  
--  Make sure that we balance
  SELECT SUM(glseries_amount), MAX(glseries_distdate) INTO _delta, _discrepDate
    FROM glseries
   WHERE (glseries_sequence=pSequence);
  IF ( _delta <> 0 ) THEN
    IF (COALESCE(fetchMetricValue('GLCompanySize'),0) = 0) THEN
      SELECT accnt_id INTO _discrepAccntid
        FROM accnt, metric
       WHERE ((metric_name='GLSeriesDiscrepancyAccount')
         AND  (accnt_id=CAST(metric_value AS INTEGER)));
    ELSE
       SELECT company_dscrp_accnt_id INTO _discrepAccntid
        FROM company
          JOIN accnt ON (accnt_company=company_number) 
          JOIN glseries ON (glseries_accnt_id=accnt_id)
       WHERE (glseries_sequence=pSequence)
       LIMIT 1;
    END IF;

    IF (NOT FOUND) THEN
      RETURN -5;
    END IF;
    
    INSERT INTO glseries
           ( glseries_sequence, glseries_source, glseries_doctype, glseries_docnumber,
             glseries_accnt_id, glseries_amount, glseries_distdate, glseries_notes )
    SELECT glseries_sequence, glseries_source, glseries_doctype, glseries_docnumber,
             _discrepAccntid, (_delta * -1), _discrepDate, 'G/L Series Discrepancy'
      FROM glseries
     WHERE (glseries_sequence=pSequence)
     LIMIT 1;
  END IF;

--  March through the glseries members, posting them one at a time
  FOR _glseries IN SELECT glseries_source, glseries_doctype, glseries_docnumber,
                          glseries_accnt_id, glseries_distdate, glseries_notes,
                          glseries_misc_id,
                          SUM(glseries_amount) as amount
                     FROM glseries
                    WHERE ((glseries_amount<>0.0)
                      AND  (glseries_sequence=pSequence))
                    GROUP BY glseries_source, glseries_doctype, glseries_docnumber,
                             glseries_accnt_id, glseries_distdate, glseries_notes,
                             glseries_misc_id LOOP

-- refuse to accept postings into closed periods
    IF (SELECT BOOL_AND(COALESCE(period_closed, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (_glseries.glseries_distdate BETWEEN period_start AND period_end)
        WHERE (accnt_id = _glseries.glseries_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to closed period (%).', _glseries.glseries_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

-- refuse to accept postings into frozen periods without proper priv
    IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
               BOOL_AND(COALESCE(period_freeze, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (_glseries.glseries_distdate BETWEEN period_start AND period_end)
        WHERE (accnt_id = _glseries.glseries_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to frozen period (%).', _glseries.glseries_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

-- refuse to accept postings into nonexistent periods
    IF NOT EXISTS(SELECT period_id
                  FROM period
                  WHERE (_glseries.glseries_distdate BETWEEN period_start AND period_end)) THEN
      RAISE EXCEPTION 'Cannot post to nonexistent period (%).', pDistDate;
    END IF;

    IF (_glseries.amount != 0 OR pPostZero) THEN
      IF (fetchMetricBool('UseJournals')) THEN
       INSERT INTO sltrans
        ( sltrans_posted, sltrans_created, sltrans_date, sltrans_misc_id,
          sltrans_sequence, sltrans_accnt_id, sltrans_source, sltrans_notes,
          sltrans_doctype, sltrans_docnumber, sltrans_amount, sltrans_journalnumber )
        VALUES
        ( FALSE, CURRENT_TIMESTAMP, _glseries.glseries_distdate, _glseries.glseries_misc_id,
          pSequence, _glseries.glseries_accnt_id, _glseries.glseries_source, _glseries.glseries_notes,
          _glseries.glseries_doctype, _glseries.glseries_docnumber, _glseries.amount, pJournalNumber );      
      ELSE
       INSERT INTO gltrans
        ( gltrans_posted, gltrans_exported, gltrans_created, gltrans_date, gltrans_misc_id,
          gltrans_sequence, gltrans_accnt_id, gltrans_source, gltrans_notes,
          gltrans_doctype, gltrans_docnumber, gltrans_amount, gltrans_journalnumber )
        VALUES
        ( FALSE, FALSE, CURRENT_TIMESTAMP, _glseries.glseries_distdate, _glseries.glseries_misc_id,
          pSequence, _glseries.glseries_accnt_id, _glseries.glseries_source, _glseries.glseries_notes,
          _glseries.glseries_doctype, _glseries.glseries_docnumber, _glseries.amount, pJournalNumber );
      END IF;
      
      _transCount := _transCount + 1;
    END IF;
  END LOOP;

--  Delete all of the posted glseries members
  DELETE FROM glseries
  WHERE (glseries_sequence=pSequence);

  PERFORM postIntoTrialBalance(pSequence);

  RETURN _transCount;

END;

Function: public.postglseriesnosumm(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  _journalNumber INTEGER;
  _returnValue INTEGER;

BEGIN

  SELECT postGLSeriesNoSumm(pSequence, fetchJournalNumber('G/L')) INTO _returnValue;
  RETURN _returnValue;

END;

Function: public.postglseriesnosumm(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _glseries RECORD;
  _transCount INTEGER := 0;
  _rows INTEGER;

BEGIN

/*  Make sure we don't create an imbalance across companies.
    The 'IgnoreCompanyBalance' metric is a back door mechanism to
    allow legacy users to create transactions accross companies if
    they have been using the company segment for something else
    and they MUST continue to be able to do so.  It can only be 
    implemented by direct sql update to the metric table and should 
    otherwise be discouraged.
*/  
  IF (COALESCE(fetchMetricValue('GLCompanySize'),0) > 0 
    AND fetchMetricBool('IgnoreCompany') = false)  THEN

    SELECT count(accnt_company) INTO _rows
    FROM (
      SELECT DISTINCT accnt_company
      FROM accnt 
        JOIN glseries ON (glseries_accnt_id=accnt_id)
      WHERE (glseries_sequence=pSequence)) _data;
    
    IF (_rows > 1) THEN
      RAISE EXCEPTION 'G/L Series can not be posted because multiple companies are referenced in the same series.';
    END IF;
  END IF;
  
--  Make sure that we balance
  IF ( ( SELECT SUM(glseries_amount)
         FROM glseries
         WHERE (glseries_sequence=pSequence) ) <> 0 ) THEN
    RETURN -1;
  END IF;

--  March through the glseries members, posting them one at a time
  FOR _glseries IN SELECT glseries_source, glseries_doctype, glseries_docnumber,
                          glseries_accnt_id, glseries_distdate, glseries_notes,
                          glseries_misc_id, glseries_amount as amount
                     FROM glseries
                    WHERE ((glseries_amount<>0.0)
                      AND  (glseries_sequence=pSequence)) LOOP

-- refuse to accept postings into closed periods
    IF (SELECT BOOL_AND(COALESCE(period_closed, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (_glseries.glseries_distdate BETWEEN period_start AND period_end)
        WHERE (accnt_id = _glseries.glseries_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to closed period (%).', _glseries.glseries_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

-- refuse to accept postings into frozen periods without proper priv
    IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
               BOOL_AND(COALESCE(period_freeze, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (_glseries.glseries_distdate BETWEEN period_start AND period_end)
        WHERE (accnt_id = _glseries.glseries_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to frozen period (%).', _glseries.glseries_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

-- refuse to accept postings into nonexistent periods
    IF NOT EXISTS(SELECT period_id
                  FROM period
                  WHERE (_glseries.glseries_distdate BETWEEN period_start AND period_end)) THEN
      RAISE EXCEPTION 'Cannot post to nonexistent period (%).', pDistDate;
    END IF;

    IF (fetchMetricBool('UseJournals')) THEN
      INSERT INTO sltrans
      ( sltrans_posted, sltrans_created, sltrans_date, sltrans_misc_id,
        sltrans_sequence, sltrans_accnt_id, sltrans_source, sltrans_notes,
        sltrans_doctype, sltrans_docnumber, sltrans_amount, sltrans_journalnumber )
      VALUES
      ( FALSE, CURRENT_TIMESTAMP, _glseries.glseries_distdate, _glseries.glseries_misc_id,
        pSequence, _glseries.glseries_accnt_id, _glseries.glseries_source, _glseries.glseries_notes,
        _glseries.glseries_doctype, _glseries.glseries_docnumber, _glseries.amount, pJournalNumber );
    ELSE
      INSERT INTO gltrans
      ( gltrans_posted, gltrans_exported, gltrans_created, gltrans_date, gltrans_misc_id,
        gltrans_sequence, gltrans_accnt_id, gltrans_source, gltrans_notes,
        gltrans_doctype, gltrans_docnumber, gltrans_amount, gltrans_journalnumber )
      VALUES
      ( FALSE, FALSE, CURRENT_TIMESTAMP, _glseries.glseries_distdate, _glseries.glseries_misc_id,
        pSequence, _glseries.glseries_accnt_id, _glseries.glseries_source, _glseries.glseries_notes,
        _glseries.glseries_doctype, _glseries.glseries_docnumber, _glseries.amount, pJournalNumber );
    END IF;

    _transCount := _transCount + 1;

  END LOOP;

--  Delete all of the posted glseries members
  DELETE FROM glseries
  WHERE (glseries_sequence=pSequence);

  PERFORM postIntoTrialBalance(pSequence);

  RETURN _transCount;

END;

Function: public.postintoinvbalance(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvhistId ALIAS FOR $1;
  _invbalid INTEGER;
  _r RECORD;
  _count INTEGER;
  _qty NUMERIC;

BEGIN

--  Grab the invhist record to post
  SELECT invhist_id, invhist_transdate, invhist_itemsite_id, invhist_transtype,
         invhist_invqty, invhist_unitcost, invhistSense(invhist_id) AS sense,
         period_id INTO _r
  FROM invhist
    JOIN itemsite ON (itemsite_id=invhist_itemsite_id)
    LEFT OUTER JOIN period ON (invhist_transdate::date BETWEEN period_start AND period_end)
  WHERE ( invhist_id=pInvhistId );

  GET DIAGNOSTICS _count = ROW_COUNT;

--  If we can post into a Inv Balance, do so
  IF ( _count > 0 ) THEN

--  Validate
    IF (_r.period_id IS NULL) THEN
      RAISE EXCEPTION 'No accounting period exists for invhist_id %, transaction date %.  Transaction can not be posted.', _r.invhist_id, formatDate(_r.invhist_transdate);
    END IF;

--  If cycle count, then we need to reference balance which needs to be accurate
--    IF (_r.invhist_transtype = 'CC') THEN
--      PERFORM forwardupdateitemsite(_r.invhist_itemsite_id);
--    END IF;

--  Try to find an existing invbal
    SELECT 
      invbal_id, 
--      CASE WHEN (_r.invhist_transtype != 'CC') THEN _r.invhist_invqty ELSE _r.invhist_invqty - invbal_qoh_ending END 
      _r.invhist_invqty
      INTO _invbalid, _qty
    FROM invbal
    WHERE ( (invbal_period_id=_r.period_id)
      AND (invbal_itemsite_id=_r.invhist_itemsite_id) );

    GET DIAGNOSTICS _count = ROW_COUNT;
    IF (_count > 0) THEN

--  We found a invbal, update it with the Inventory Transaction
--  Note - two stage update to avoid any funny value caching logic
    IF (_r.sense * _qty > 0) THEN
      UPDATE invbal SET 
        invbal_qty_in = (invbal_qty_in + abs(_qty)),
        invbal_value_in = (invbal_value_in + abs(_qty) * _r.invhist_unitcost)
      WHERE (invbal_id=_invbalid);
    ELSIF (_r.sense * _qty < 0) THEN
      UPDATE invbal SET 
        invbal_qty_out = (invbal_qty_out + abs(_qty)),
        invbal_value_out = (invbal_value_out + abs(_qty) *  _r.invhist_unitcost)
      WHERE (invbal_id=_invbalid);
    END IF;

    -- Non-netable transactions have their own balances
    IF (_r.invhist_transtype = 'NN') THEN
      UPDATE invbal SET 
        invbal_nn_in = (invbal_nn_in + _qty * -1),
        invbal_nnval_in = (invbal_nnval_in + _qty * -1 * _r.invhist_unitcost)
      WHERE (invbal_id=_invbalid);
    END IF;

    UPDATE invbal SET 
      invbal_qoh_ending = (invbal_qoh_beginning + invbal_qty_in - invbal_qty_out),
      invbal_value_ending = (invbal_value_beginning + invbal_value_in - invbal_value_out),
      invbal_nn_ending = (invbal_nn_beginning + invbal_nn_in - invbal_nn_out),
      invbal_nnval_ending = (invbal_nnval_beginning + invbal_nnval_in - invbal_nnval_out),
      invbal_dirty=true
    WHERE (invbal_id=_invbalid);
  ELSE

--  No existing invbal, make one
    SELECT NEXTVAL('invbal_invbal_id_seq') INTO _invbalid;
      INSERT INTO invbal
        ( invbal_id, invbal_itemsite_id, invbal_period_id,
          invbal_qoh_beginning,
          invbal_qoh_ending,
          invbal_qty_in,
          invbal_qty_out,
          invbal_value_beginning,
          invbal_value_ending,
          invbal_value_in,
          invbal_value_out,
          invbal_nn_beginning,
          invbal_nn_ending,
          invbal_nn_in,
          invbal_nn_out,
          invbal_nnval_beginning,
          invbal_nnval_ending,
          invbal_nnval_in,
          invbal_nnval_out,
          invbal_dirty )
      VALUES
        ( _invbalid, _r.invhist_itemsite_id, _r.period_id,
         -- Netable
          0, 
          _r.invhist_invqty * _r.sense,
          CASE WHEN (_r.sense > 0) THEN _r.invhist_invqty
               ELSE 0
          END,
          CASE WHEN (_r.sense < 0) THEN (_r.invhist_invqty)
               ELSE 0
          END,
          0,
          _r.invhist_invqty * _r.invhist_unitcost * _r.sense,
          CASE WHEN (_r.sense > 0) THEN _r.invhist_invqty * _r.invhist_unitcost
               ELSE 0
          END,
          CASE WHEN (_r.sense < 0) THEN (_r.invhist_invqty  * _r.invhist_unitcost)
               ELSE 0
          END,
          -- Non netable
          0, 
          CASE WHEN (_r.invhist_transtype='NN') THEN _r.invhist_invqty * -1
               ELSE 0
          END,
          CASE WHEN (_r.sense > 0 AND _r.invhist_transtype='NN') THEN _r.invhist_invqty * -1
               ELSE 0
          END,
          CASE WHEN (_r.sense < 0 AND _r.invhist_transtype='NN') THEN _r.invhist_invqty * -1
               ELSE 0
          END,
          0,
          CASE WHEN (_r.invhist_transtype='NN') THEN _r.invhist_invqty * _r.invhist_unitcost * -1
               ELSE 0
          END,
          CASE WHEN (_r.sense > 0 AND _r.invhist_transtype='NN') THEN _r.invhist_invqty * -1 * _r.invhist_unitcost
               ELSE 0
          END,
          CASE WHEN (_r.sense < 0 AND _r.invhist_transtype='NN') THEN (_r.invhist_invqty  * -1 * _r.invhist_unitcost)
               ELSE 0
          END,
          true );
    END IF;
  ELSE
    RETURN FALSE;
  END IF;

  RETURN TRUE;

END;

Function: public.postintotrialbalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  _trialbalid INTEGER;
  _r RECORD;

BEGIN

--  March through all of the G/L Transactions for the passed sequence that are not posted
  FOR _r IN SELECT gltrans_id, gltrans_date, gltrans_accnt_id, gltrans_amount,
                   accnt_forwardupdate, period_id, period_closed, period_freeze
            FROM accnt, gltrans LEFT OUTER JOIN period ON (gltrans_date BETWEEN period_start AND period_end)
            WHERE ( (gltrans_accnt_id=accnt_id)
             AND (NOT gltrans_posted)
             AND (NOT gltrans_deleted)
             AND (gltrans_sequence=pSequence) ) LOOP

--  If we can post into a Trial Balance, do so
    IF ( (NOT _r.period_closed) AND ( (NOT _r.period_freeze) OR (checkPrivilege('PostFrozenPeriod')) ) ) THEN

--  Try to find an existing trialbal
      SELECT trialbal_id INTO _trialbalid
      FROM trialbal
      WHERE ( (trialbal_period_id=_r.period_id)
       AND (trialbal_accnt_id=_r.gltrans_accnt_id) );
      IF (FOUND) THEN

--  We found a trialbal, update it with the G/L Transaction
--  Note - two stage update to avoid any funny value caching logic
        IF (_r.gltrans_amount > 0) THEN
          UPDATE trialbal
          SET trialbal_credits = (trialbal_credits + _r.gltrans_amount)
          WHERE (trialbal_id=_trialbalid);
        ELSE
          UPDATE trialbal
          SET trialbal_debits = (trialbal_debits + (_r.gltrans_amount * -1))
          WHERE (trialbal_id=_trialbalid);
        END IF;

        UPDATE trialbal
        SET trialbal_ending = (trialbal_beginning - trialbal_debits + trialbal_credits),
            trialbal_dirty=TRUE
        WHERE (trialbal_id=_trialbalid);
      ELSE

--  No existing trialbal, make one
        SELECT NEXTVAL('trialbal_trialbal_id_seq') INTO _trialbalid;
        INSERT INTO trialbal
        ( trialbal_id, trialbal_accnt_id, trialbal_period_id,
          trialbal_beginning, trialbal_dirty,
          trialbal_ending,
          trialbal_credits,
          trialbal_debits )
        VALUES
        ( _trialbalid, _r.gltrans_accnt_id, _r.period_id,
          0, TRUE,
          _r.gltrans_amount,
          CASE WHEN (_r.gltrans_amount > 0) THEN _r.gltrans_amount
               ELSE 0
          END,
          CASE WHEN (_r.gltrans_amount < 0) THEN (_r.gltrans_amount * -1)
               ELSE 0
          END );
      END IF;

--  Forward update if we should
      IF (_r.accnt_forwardupdate AND fetchmetricbool('ManualForwardUpdate')) THEN
        PERFORM forwardUpdateTrialBalance(_trialbalid);
      END IF;

--  Mark the G/L Transaction as posted
      UPDATE gltrans
      SET gltrans_posted=TRUE
      WHERE (gltrans_id=_r.gltrans_id);

    END IF;

  END LOOP;

  RETURN 1;

END;

Function: public.postinvhist(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvhistId ALIAS FOR $1;
  _r RECORD;
BEGIN

    IF ( SELECT metric_value
        FROM metric
        WHERE ((metric_name = 'EnableAsOfQOH')
        AND (metric_value = 't'))) THEN
      IF (NOT postIntoInvBalance(pInvhistId)) THEN
        RAISE EXCEPTION 'Post into Inventory Balance for invhist_id=% was unsuccessful',pInvhistId;
      END IF;
    END IF;

    --Update itemsite qoh and change posted flag
    UPDATE itemsite SET 
      itemsite_qtyonhand = (itemsite_qtyonhand + (invhist_invqty * invhistSense(invhist_id))),
      itemsite_value = itemsite_value + invhist_value_after - invhist_value_before
    FROM invhist
    WHERE ( (itemsite_id=invhist_itemsite_id)
    AND (invhist_id=pInvhistId)
    AND (NOT invhist_posted) );

    --Flag as posted
    UPDATE invhist SET
      invhist_posted=TRUE
    WHERE ( (invhist_id=pInvhistId)
    AND (invhist_posted=FALSE) );

RETURN TRUE;

END;

Function: public.postinvoice(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  _return INTEGER;

BEGIN

  SELECT postInvoice(pInvcheadid, fetchJournalNumber('AR-IN')) INTO _return;

  RETURN _return;

END;

Function: public.postinvoice(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _itemlocSeries INTEGER;
  _return INTEGER;

BEGIN

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  SELECT postInvoice(pInvcheadid, pJournalNumber, _itemlocseries) INTO _return;

  RETURN _return;

END;

Function: public.postinvoice(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  _aropenid INTEGER;
  _cohistid INTEGER;
  _itemlocSeries INTEGER := 0;
  _invhistid INTEGER := 0;
  _amount NUMERIC;
  _roundedBase NUMERIC;
  _sequence INTEGER;
  _r RECORD;
  _p RECORD;
  _test INTEGER;
  _totalAmount          NUMERIC := 0;
  _totalRoundedBase     NUMERIC := 0;
  _totalAmountBase      NUMERIC := 0;
  _appliedAmount        NUMERIC := 0;
  _commissionDue        NUMERIC := 0;
  _tmpAccntId INTEGER;
  _tmpCurrId  INTEGER;
  _firstExchDate        DATE;
  _glDate		DATE;
  _exchGain             NUMERIC := 0;

BEGIN

  IF ( ( SELECT invchead_posted
         FROM invchead
         WHERE (invchead_id=pInvcheadid) ) ) THEN
    RETURN -10;
  END IF;

--  Cache some parameters
  SELECT invchead.*, fetchGLSequence() AS sequence,
         findFreightAccount(invchead_cust_id) AS freightaccntid,
         findARAccount(invchead_cust_id) AS araccntid,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM invcheadtax
           WHERE ( (taxhist_parent_id = invchead_id)
             AND   (taxhist_taxtype_id = getFreightTaxtypeId()) ) ) AS freighttax,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM invcheadtax
           WHERE ( (taxhist_parent_id = invchead_id)
             AND   (taxhist_taxtype_id = getAdjustmentTaxtypeId()) ) ) AS adjtax
       INTO _p 
  FROM invchead
  WHERE (invchead_id=pInvcheadid);

  _itemlocSeries = pItemlocSeries;

  _glDate := COALESCE(_p.invchead_gldistdate, _p.invchead_invcdate);

  IF (_p.invchead_salesrep_id < 0) THEN
    RAISE NOTICE 'Patch negative invchead_salesrep_id until invchead_salesrep_id is a true fkey';
    _p.invchead_salesrep_id := NULL;
  END IF;

-- the 1st MC iteration used the cohead_orderdate so we could get curr exch
-- gain/loss between the sales and invoice dates, but see issue 3892.  leave
-- this condition TRUE until we make this configurable or decide not to.
  IF TRUE THEN
      _firstExchDate := _p.invchead_invcdate;
  ELSE
-- can we save a select by using: _firstExchDate := _p.invchead_orderdate;
      SELECT cohead_orderdate INTO _firstExchDate
      FROM cohead JOIN invchead ON (cohead_number = invchead_ordernumber)
      WHERE (invchead_id = pInvcheadid);
  END IF;

--  Start by handling taxes
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.invchead_curr_id, round(sum(taxdetail_tax),2), _firstExchDate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('I', pInvcheadid, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _p.sequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                _r.tax_sales_accnt_id, 
                                _r.taxbasevalue,
                                _glDate, _p.invchead_billto_name );

    _totalAmount := _totalAmount + _r.tax;
    _totalRoundedBase := _totalRoundedBase + _r.taxbasevalue;  
  END LOOP;

-- Update item tax records with posting data
    UPDATE invcitemtax SET 
      taxhist_docdate=_firstExchDate,
      taxhist_distdate=_glDate,
      taxhist_curr_id=_p.invchead_curr_id,
      taxhist_curr_rate=curr_rate,
      taxhist_journalnumber=pJournalNumber
    FROM invchead
     JOIN invcitem ON (invchead_id=invcitem_invchead_id), 
     curr_rate
    WHERE ((invchead_id=pInvcheadId)
      AND (taxhist_parent_id=invcitem_id)
      AND (_p.invchead_curr_id=curr_id)
      AND ( _firstExchDate BETWEEN curr_effective 
                           AND curr_expires) );

-- Update Invchead taxes (Freight and Adjustments) with posting data
    UPDATE invcheadtax SET 
      taxhist_docdate=_firstExchDate,
      taxhist_distdate=_glDate,
      taxhist_curr_id=_p.invchead_curr_id,
      taxhist_curr_rate=curr_rate,
      taxhist_journalnumber=pJournalNumber
    FROM curr_rate
    WHERE ((taxhist_parent_id=pInvcheadid)
      AND (_p.invchead_curr_id=curr_id)
      AND ( _firstExchDate BETWEEN curr_effective 
                           AND curr_expires) );

--  March through the Non-Misc. Invcitems
  FOR _r IN SELECT *
            FROM invoiceitem
            WHERE ( (invcitem_invchead_id = pInvcheadid)
              AND   (invcitem_item_id <> -1) ) LOOP

--  Cache the amount due for this line
    _amount := _r.extprice;

    IF (_amount > 0) THEN
--  Credit the Sales Account for the invcitem item
      IF (_r.invcitem_rev_accnt_id IS NOT NULL) THEN
        SELECT getPrjAccntId(_p.invchead_prj_id, _r.invcitem_rev_accnt_id)
	INTO _tmpAccntId;
      ELSEIF (_r.itemsite_id IS NULL) THEN
	SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
	INTO _tmpAccntId
	FROM salesaccnt
	WHERE (salesaccnt_id=findSalesAccnt(_r.invcitem_item_id, 'I', _p.invchead_cust_id,
                                            _p.invchead_saletype_id, _p.invchead_shipzone_id));
      ELSE
	SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
	INTO _tmpAccntId
	FROM salesaccnt
	WHERE (salesaccnt_id=findSalesAccnt(_r.itemsite_id, 'IS', _p.invchead_cust_id,
                                            _p.invchead_saletype_id, _p.invchead_shipzone_id));
      END IF;

--  If the Sales Account Assignment was not found then punt
      IF (NOT FOUND) THEN
        PERFORM deleteGLSeries(_p.sequence);
        DELETE FROM cohist
         WHERE ((cohist_sequence=_p.sequence)
           AND  (cohist_invcnumber=_p.invchead_invcnumber));
        RETURN -11;
      END IF;

      _roundedBase := round(currToBase(_p.invchead_curr_id, _amount, _firstExchDate), 2);
      SELECT insertIntoGLSeries( _p.sequence, 'A/R', 'IN',
                                 _p.invchead_invcnumber, _tmpAccntId,
                                 _roundedBase, _glDate, _p.invchead_billto_name ) INTO _test;

      _totalAmount := (_totalAmount + _amount);
      _totalRoundedBase := _totalRoundedBase + _roundedBase;
      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
    END IF;

    _totalAmount := _totalAmount;
    _totalRoundedBase := _totalRoundedBase;

--  Record Sales History for this S/O Item
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_sequence, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.invchead_cust_id, _r.itemsite_id, _p.invchead_shipto_id,
      _p.invchead_shipdate, _p.invchead_shipvia,
      COALESCE(_p.invchead_ordernumber, _r.cohead_number), _p.invchead_ponumber, _p.invchead_orderdate,
      'I', _p.invchead_invcnumber, _p.invchead_invcdate,
      _r.qty, _r.unitprice, _r.unitcost,
      _p.invchead_salesrep_id, (_p.invchead_commission * _r.extprice), FALSE,
      _p.invchead_billto_name, _p.invchead_billto_address1,
      _p.invchead_billto_address2, _p.invchead_billto_address3,
      _p.invchead_billto_city, _p.invchead_billto_state, _p.invchead_billto_zipcode,
      _p.invchead_shipto_name, _p.invchead_shipto_address1,
      _p.invchead_shipto_address2, _p.invchead_shipto_address3,
      _p.invchead_shipto_city, _p.invchead_shipto_state,
      _p.invchead_shipto_zipcode, _p.invchead_curr_id,
      _p.sequence, _r.invcitem_taxtype_id, _p.invchead_taxzone_id,
      _p.invchead_shipzone_id, _p.invchead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber
    FROM invcitemtax
    WHERE (taxhist_parent_id=_r.invcitem_id);

  END LOOP;

--  March through the Misc. Invcitems
  FOR _r IN SELECT *
            FROM invoiceitem JOIN salescat ON (salescat_id = invcitem_salescat_id)
            WHERE ( (invcitem_item_id = -1)
              AND   (invcitem_invchead_id=pInvcheadid) ) LOOP

--  Cache the amount due for this line and the commission due for such
    _amount := _r.extprice;

    IF (_amount > 0) THEN
--  Credit the Sales Account for the invcitem item
      _roundedBase = round(currToBase(_p.invchead_curr_id, _amount,
                                      _firstExchDate), 2);
      SELECT insertIntoGLSeries( _p.sequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 getPrjAccntId(_p.invchead_prj_id, COALESCE(_r.invcitem_rev_accnt_id, _r.salescat_sales_accnt_id)), 
                                 _roundedBase,
                                 _glDate, _p.invchead_billto_name ) INTO _test;
      IF (_test < 0) THEN
        PERFORM deleteGLSeries(_p.sequence);
        DELETE FROM cohist
         WHERE ((cohist_sequence=_p.sequence)
           AND  (cohist_invcnumber=_p.invchead_invcnumber));
        RETURN _test;
      END IF;

      _totalAmount := (_totalAmount + _amount);
      _totalRoundedBase :=  _totalRoundedBase + _roundedBase;
      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
    END IF;

--  Record Sales History for this S/O Item
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_sequence, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.invchead_cust_id, -1, _p.invchead_shipto_id,
      'M', (_r.invcitem_number || '-' || _r.invcitem_descrip),
      _p.invchead_shipdate, _p.invchead_shipvia,
      COALESCE(_p.invchead_ordernumber, _r.cohead_number), _p.invchead_ponumber, _p.invchead_orderdate,
      'I', _p.invchead_invcnumber, _p.invchead_invcdate,
      _r.qty, _r.unitprice, 0,
      _p.invchead_salesrep_id, (_p.invchead_commission * _r.extprice), FALSE,
      _p.invchead_billto_name, _p.invchead_billto_address1,
      _p.invchead_billto_address2, _p.invchead_billto_address3,
      _p.invchead_billto_city, _p.invchead_billto_state, _p.invchead_billto_zipcode,
      _p.invchead_shipto_name, _p.invchead_shipto_address1,
      _p.invchead_shipto_address2, _p.invchead_shipto_address3,
      _p.invchead_shipto_city, _p.invchead_shipto_state,
      _p.invchead_shipto_zipcode, _p.invchead_curr_id,
      _p.sequence, _r.invcitem_taxtype_id, _p.invchead_taxzone_id,
      _p.invchead_shipzone_id, _p.invchead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber
    FROM invcitemtax
    WHERE (taxhist_parent_id=_r.invcitem_id);

  END LOOP;

--  Credit the Freight Account for Freight Charges
  IF (_p.invchead_freight <> 0) THEN
    IF (_p.freightaccntid <> -1) THEN
      _roundedBase = round(currToBase(_p.invchead_curr_id, _p.invchead_freight,
                                      _firstExchDate), 2);
      SELECT insertIntoGLSeries( _p.sequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 getPrjAccntId(_p.invchead_prj_id,_p.freightaccntid), 
                                 _roundedBase,
                                 _glDate, _p.invchead_billto_name ) INTO _test;

--  Cache the Freight Amount distributed
        _totalAmount := (_totalAmount + _p.invchead_freight);
        _totalRoundedBase := _totalRoundedBase + _roundedBase;
    ELSE
      _test := -14;
    END IF;

--  If the Freight Account was not found then punt
    IF (_test < 0) THEN
      PERFORM deleteGLSeries(_p.sequence);
      DELETE FROM cohist
       WHERE ((cohist_sequence=_p.sequence)
         AND  (cohist_invcnumber=_p.invchead_invcnumber));
      RETURN _test;
    END IF;

--  Record Sales History for the Freight
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_sequence, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.invchead_cust_id, -1, _p.invchead_shipto_id,
      'F', 'Freight',
      _p.invchead_shipdate, _p.invchead_shipvia,
      _p.invchead_ordernumber, _p.invchead_ponumber, _p.invchead_orderdate,
      'I', _p.invchead_invcnumber, _p.invchead_invcdate,
      1, _p.invchead_freight, _p.invchead_freight,
      _p.invchead_salesrep_id, 0, FALSE,
      _p.invchead_billto_name, _p.invchead_billto_address1,
      _p.invchead_billto_address2, _p.invchead_billto_address3,
      _p.invchead_billto_city, _p.invchead_billto_state, _p.invchead_billto_zipcode,
      _p.invchead_shipto_name, _p.invchead_shipto_address1,
      _p.invchead_shipto_address2, _p.invchead_shipto_address3,
      _p.invchead_shipto_city, _p.invchead_shipto_state,
      _p.invchead_shipto_zipcode, _p.invchead_curr_id,
      _p.sequence, getFreightTaxtypeId(), _p.invchead_taxzone_id,
      _p.invchead_shipzone_id, _p.invchead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber
    FROM invcheadtax
    WHERE ( (taxhist_parent_id=_p.invchead_id)
      AND   (taxhist_taxtype_id=getFreightTaxtypeId()) );

  END IF;

--  Credit the Misc. Account for Miscellaneous Charges
  IF (_p.invchead_misc_amount <> 0) THEN
    _roundedBase := round(currToBase(_p.invchead_curr_id, _p.invchead_misc_amount,
                                     _firstExchDate), 2);
    SELECT insertIntoGLSeries( _p.sequence, 'A/R', 'IN', _p.invchead_invcnumber,
                               getPrjAccntId(_p.invchead_prj_id, _p.invchead_misc_accnt_id), 
                               _roundedBase,
                               _glDate, _p.invchead_billto_name ) INTO _test;

--  If the Misc. Charges Account was not found then punt
    IF (_test < 0) THEN
      PERFORM deleteGLSeries(_p.sequence);
      DELETE FROM cohist
       WHERE ((cohist_sequence=_p.sequence)
         AND  (cohist_invcnumber=_p.invchead_invcnumber));
      RETURN _test;
    END IF;

--  Cache the Misc. Amount distributed
    _totalAmount := (_totalAmount + _p.invchead_misc_amount);
    _totalRoundedBase := _totalRoundedBase + _roundedBase;

--  Record Sales History for the Misc. Charge
    INSERT INTO cohist
    ( cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip, cohist_misc_id,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_sequence,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _p.invchead_cust_id, -1, _p.invchead_shipto_id,
      'M', _p.invchead_misc_descrip, _p.invchead_misc_accnt_id,
      _p.invchead_shipdate, _p.invchead_shipvia,
      _p.invchead_ordernumber, _p.invchead_ponumber, _p.invchead_orderdate,
      'I', _p.invchead_invcnumber, _p.invchead_invcdate,
      1, _p.invchead_misc_amount, _p.invchead_misc_amount,
      _p.invchead_salesrep_id, 0, FALSE,
      _p.invchead_billto_name, _p.invchead_billto_address1,
      _p.invchead_billto_address2, _p.invchead_billto_address3,
      _p.invchead_billto_city, _p.invchead_billto_state, _p.invchead_billto_zipcode,
      _p.invchead_shipto_name, _p.invchead_shipto_address1,
      _p.invchead_shipto_address2, _p.invchead_shipto_address3,
      _p.invchead_shipto_city, _p.invchead_shipto_state,
      _p.invchead_shipto_zipcode, _p.invchead_curr_id,
      _p.sequence,
      _p.invchead_shipzone_id, _p.invchead_saletype_id );

  END IF;

--  Record Sales History for the Tax Adjustment
  IF (_p.adjtax <> 0) THEN
    SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
    INSERT INTO cohist
    ( cohist_id, cohist_cust_id, cohist_itemsite_id, cohist_shipto_id,
      cohist_misc_type, cohist_misc_descrip,
      cohist_shipdate, cohist_shipvia,
      cohist_ordernumber, cohist_ponumber, cohist_orderdate,
      cohist_doctype, cohist_invcnumber, cohist_invcdate,
      cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
      cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
      cohist_billtoname, cohist_billtoaddress1,
      cohist_billtoaddress2, cohist_billtoaddress3,
      cohist_billtocity, cohist_billtostate, cohist_billtozip,
      cohist_shiptoname, cohist_shiptoaddress1,
      cohist_shiptoaddress2, cohist_shiptoaddress3,
      cohist_shiptocity, cohist_shiptostate, cohist_shiptozip,
      cohist_curr_id, cohist_sequence, cohist_taxtype_id, cohist_taxzone_id,
      cohist_shipzone_id, cohist_saletype_id )
    VALUES
    ( _cohistid, _p.invchead_cust_id, -1, _p.invchead_shipto_id,
      'T', 'Misc Tax Adjustment',
      _p.invchead_shipdate, _p.invchead_shipvia,
      _p.invchead_ordernumber, _p.invchead_ponumber, _p.invchead_orderdate,
      'I', _p.invchead_invcnumber, _p.invchead_invcdate,
      1, 0.0, 0.0,
      _p.invchead_salesrep_id, 0, FALSE,
      _p.invchead_billto_name, _p.invchead_billto_address1,
      _p.invchead_billto_address2, _p.invchead_billto_address3,
      _p.invchead_billto_city, _p.invchead_billto_state, _p.invchead_billto_zipcode,
      _p.invchead_shipto_name, _p.invchead_shipto_address1,
      _p.invchead_shipto_address2, _p.invchead_shipto_address3,
      _p.invchead_shipto_city, _p.invchead_shipto_state,
      _p.invchead_shipto_zipcode, _p.invchead_curr_id,
      _p.sequence, getAdjustmentTaxtypeId(), _p.invchead_taxzone_id,
      _p.invchead_shipzone_id, _p.invchead_saletype_id );
    INSERT INTO cohisttax
    ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
      taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
      taxhist_percent, taxhist_amount, taxhist_tax,
      taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
      taxhist_journalnumber )
    SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber
    FROM invcheadtax
    WHERE ( (taxhist_parent_id=_p.invchead_id)
      AND   (taxhist_taxtype_id=getAdjustmentTaxtypeId()) );

  END IF;

-- ToDo: handle rounding errors
    _exchGain := currGain(_p.invchead_curr_id, _totalAmount,
                          _firstExchDate, _glDate);
    IF (_exchGain <> 0) THEN
        SELECT insertIntoGLSeries( _p.sequence, 'A/R', 'IN',
                                   _p.invchead_invcnumber, getGainLossAccntId(_p.araccntid),
                                   round(_exchGain, 2) * -1,
                                   _glDate, _p.invchead_billto_name ) INTO _test ;
        IF (_test < 0) THEN
          PERFORM deleteGLSeries(_p.sequence);
          DELETE FROM cohist
           WHERE ((cohist_sequence=_p.sequence)
             AND  (cohist_invcnumber=_p.invchead_invcnumber));
          RETURN _test;
        END IF;
    END IF;

--  Debit A/R for the total Amount
  IF (_totalRoundedBase <> 0) THEN
    IF (_p.araccntid != -1) THEN
      PERFORM insertIntoGLSeries( _p.sequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                  _p.araccntid, round(_totalRoundedBase * -1, 2),
                                  _glDate, _p.invchead_billto_name );
    ELSE
      PERFORM deleteGLSeries(_p.sequence);
      DELETE FROM cohist
       WHERE ((cohist_sequence=_p.sequence)
         AND  (cohist_invcnumber=_p.invchead_invcnumber));
      RETURN -17;
    END IF;
  END IF;

--  Commit the GLSeries;
  SELECT postGLSeries(_p.sequence, pJournalNumber) INTO _test;
  IF (_test < 0) THEN
    PERFORM deleteGLSeries(_p.sequence);
    DELETE FROM cohist
     WHERE ((cohist_sequence=_p.sequence)
       AND  (cohist_invcnumber=_p.invchead_invcnumber));
    RETURN _test;
  END IF;

--  Create the Invoice aropen item
  SELECT nextval('aropen_aropen_id_seq') INTO _aropenid;
  INSERT INTO aropen
  ( aropen_id, aropen_username, aropen_journalnumber,
    aropen_open, aropen_posted,
    aropen_cust_id, aropen_ponumber,
    aropen_docnumber, aropen_applyto, aropen_doctype,
    aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id,
    aropen_amount, aropen_paid,
    aropen_salesrep_id, aropen_commission_due, aropen_commission_paid,
    aropen_ordernumber, aropen_notes, aropen_cobmisc_id,
    aropen_curr_id )
  VALUES
  ( _aropenid, getEffectiveXtUser(), pJournalNumber,
    TRUE, FALSE,
    _p.invchead_cust_id, _p.invchead_ponumber,
    _p.invchead_invcnumber, _p.invchead_invcnumber, 'I',
    _p.invchead_invcdate, determineDueDate(_p.invchead_terms_id, _p.invchead_invcdate), _glDate, _p.invchead_terms_id,
    round(_totalAmount, 2), 0, 
    _p.invchead_salesrep_id, _commissionDue, FALSE,
    _p.invchead_ordernumber::text, _p.invchead_notes, pInvcheadid,
    _p.invchead_curr_id );

-- Handle the Inventory and G/L Transactions for any billed Inventory where invcitem_updateinv is true
  FOR _r IN SELECT itemsite_id AS itemsite_id, invcitem_id,
                   (invcitem_billed * invcitem_qty_invuomratio) AS qty,
                   invchead_invcnumber, invchead_cust_id AS cust_id, item_number,
                   invchead_saletype_id AS saletype_id, invchead_shipzone_id AS shipzone_id,
                   invchead_prj_id, itemsite_costmethod
            FROM invchead JOIN invcitem ON ( (invcitem_invchead_id=invchead_id) AND
                                             (invcitem_billed <> 0) AND
                                             (invcitem_updateinv) )
                          JOIN itemsite ON ( (itemsite_item_id=invcitem_item_id) AND
                                             (itemsite_warehous_id=invcitem_warehous_id) )
                          JOIN item ON (item_id=invcitem_item_id)
            WHERE (invchead_id=pInvcheadid) LOOP

--  Issue billed stock from inventory
    IF (_itemlocSeries = 0) THEN
      _itemlocSeries := NEXTVAL('itemloc_series_seq');
    END IF;
    IF (_r.itemsite_costmethod != 'J') THEN
      SELECT postInvTrans(itemsite_id, 'SH', _r.qty,
                         'S/O', 'IN', _r.invchead_invcnumber, '',
                         ('Invoice Billed ' || _r.item_number),
                         getPrjAccntId(_r.invchead_prj_id, resolveCOSAccount(itemsite_id, _r.cust_id, _r.saletype_id, _r.shipzone_id)),
                         costcat_asset_accnt_id, _itemlocSeries, _glDate) INTO _invhistid
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );
    ELSE
      RAISE DEBUG 'postInvoice(%, %, %) tried to postInvTrans a %-costed item',
                  pInvcheadid, pJournalNumber, pItemlocSeries,
                  _r.itemsite_costmethod;
    END IF;

  END LOOP;

--  Mark the invoice as posted
  UPDATE invchead
  SET invchead_posted=TRUE, invchead_gldistdate=_glDate
  WHERE (invchead_id=pInvcheadid);
 
  IF (_totalAmount > 0) THEN
    -- get a list of allocated CMs
    FOR _r IN SELECT aropen_id,
		     CASE WHEN((aropen_amount - aropen_paid) >=
                                aropenalloc_amount / (1 / aropen_curr_rate / 
                                currRate(aropenalloc_curr_id,_firstExchDate))) THEN
			      aropenalloc_amount / (1 / aropen_curr_rate / 
                                currRate(aropenalloc_curr_id,_firstExchDate))
			  ELSE (aropen_amount - aropen_paid)
		     END AS balance,
		     aropen_curr_id, aropen_curr_rate,
		     aropenalloc_doctype, aropenalloc_doc_id
                FROM aropenalloc, aropen
               WHERE ( (aropenalloc_aropen_id=aropen_id)
                 AND   ((aropenalloc_doctype='S' AND aropenalloc_doc_id=(SELECT cohead_id
                                                                           FROM cohead
                                                                          WHERE cohead_number=_p.invchead_ordernumber)) OR
                        (aropenalloc_doctype='I' AND aropenalloc_doc_id=_p.invchead_id)) ) LOOP

      _appliedAmount := _r.balance;
      IF (_totalAmount < _appliedAmount / (1 / currRate(_r.aropen_curr_id,_firstExchDate) /
                        _r.aropen_curr_rate)) THEN
        _appliedAmount := _totalAmount;
	_tmpCurrId := _p.invchead_curr_id;
      ELSE
	_tmpCurrId := _r.aropen_curr_id;
      END IF;

      -- ignore if no appliable balance
      IF (_appliedAmount > 0) THEN
        -- create an arcreditapply record linking the source c/m and the target invoice
        -- for an amount that is equal to the balance on the invoice or the balance on
        -- c/m whichever is greater.
        INSERT INTO arcreditapply
              (arcreditapply_source_aropen_id, arcreditapply_target_aropen_id,
	       arcreditapply_amount, arcreditapply_curr_id, arcreditapply_reftype, arcreditapply_ref_id)
        VALUES(_r.aropen_id, _aropenid, _appliedAmount, _tmpCurrId, 'S',  _r.aropenalloc_doc_id);

        -- call postARCreditMemoApplication(aropen_id of C/M)
        SELECT postARCreditMemoApplication(_r.aropen_id) into _test;

        -- if no error decrement the balance and contiue on
        IF (_test >= 0) THEN
          _totalAmount := _totalAmount - currToCurr(_tmpCurrId, _p.invchead_curr_id,
						    _appliedAmount, _firstExchDate);
        END IF;
      END IF;
    END LOOP;
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.postinvoices(boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostUnprinted ALIAS FOR $1;
BEGIN
  RETURN postInvoices(pPostUnprinted, FALSE);
END;

Function: public.postinvoices(boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostUnprinted ALIAS FOR $1;
  pInclZeros     ALIAS FOR $2;
BEGIN
  RETURN postInvoices(pPostUnprinted, pInclZeros, fetchJournalNumber('AR-IN'));
END;

Function: public.postinvoices(boolean, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostUnprinted ALIAS FOR $1;
  pInclZeros     ALIAS FOR $2;
  pJournalNumber ALIAS FOR $3;
  _invcheadid    INTEGER;
  _itemlocSeries INTEGER;
  _counter INTEGER;
  _r RECORD;

BEGIN

  _itemlocSeries := 0;

  IF (pInclZeros) THEN

    FOR _invcheadid IN
      SELECT invchead_id
      FROM invchead
      WHERE ( (NOT invchead_posted)
       AND (checkInvoiceSitePrivs(invchead_id))
       AND (pPostUnprinted OR invchead_printed) ) LOOP

      SELECT postInvoice(_invcheadid, pJournalNumber, _itemlocSeries) INTO _itemlocSeries;
      IF (_itemlocSeries < 0) THEN
        RETURN _itemlocSeries;
      END IF;
    END LOOP;

  ELSE

    FOR _invcheadid IN
      SELECT invchead_id
      FROM invchead LEFT OUTER JOIN invcitem ON (invchead_id=invcitem_invchead_id)
                    LEFT OUTER JOIN item ON (invcitem_item_id=item_id)  
      WHERE((NOT invchead_posted)
        AND (checkInvoiceSitePrivs(invchead_id))
        AND (pPostUnprinted OR invchead_printed))
      GROUP BY invchead_id, invchead_freight, invchead_misc_amount
      HAVING (COALESCE(SUM(round((invcitem_billed * invcitem_qty_invuomratio) * (invcitem_price /  
              CASE WHEN (item_id IS NULL) THEN 1 
              ELSE invcitem_price_invuomratio END), 2)),0)
             + invchead_freight + invchead_misc_amount) > 0 LOOP

      SELECT postInvoice(_invcheadid, pJournalNumber, _itemlocSeries) INTO _itemlocSeries;
      IF (_itemlocSeries < 0) THEN
        RETURN _itemlocSeries;
      END IF;
    END LOOP;

  END IF;

  RETURN _itemlocSeries;

END;

Function: public.postinvtrans(pinvhistid integer, pcostovrld text, ptimestamp numeric, pitemlocseries text, pcreditid text, pdebitid text, pcomments text, pdocnumber text, pordernumber integer, pordertype integer, pmodule integer, pqty timestamp with time zone, ptranstype numeric, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
-- pInvhistid is the original transaction to be returned, reversed, etc.
DECLARE
  _creditid	     INTEGER;
  _debitid	     INTEGER;
  _glreturn	     INTEGER;
  _invhistid	     INTEGER;
  _itemlocdistid     INTEGER;
  _r		     RECORD;
  _sense	     INTEGER;  -- direction in which to adjust inventory QOH
  _t		     RECORD;
  _timestamp         TIMESTAMP WITH TIME ZONE;
  _xferwhsid	     INTEGER;

BEGIN

  --  Cache item and itemsite info  
  SELECT CASE WHEN(itemsite_costmethod IN ('A','J')) THEN COALESCE(abs(pCostOvrld / pQty), avgcost(itemsite_id))
              ELSE stdCost(itemsite_item_id)
         END AS cost,
         itemsite_costmethod,
         itemsite_qtyonhand,
	 itemsite_warehous_id,
         ( (item_type = 'R') OR (itemsite_controlmethod = 'N') ) AS nocontrol,
         (itemsite_controlmethod IN ('L', 'S')) AS lotserial,
         (itemsite_loccntrl) AS loccntrl,
         itemsite_freeze AS frozen INTO _r
  FROM itemsite JOIN item ON (item_id=itemsite_item_id)
  WHERE (itemsite_id=pItemsiteid);

  --Post the Inventory Transactions
  IF (_r.nocontrol) THEN
    RETURN -1; -- non-fatal error so dont throw an exception?
  END IF;

  IF (COALESCE(pItemlocSeries,0) = 0) THEN
    RAISE EXCEPTION 'Transaction series must be provided';
  END IF;

  SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;

  IF ((pTimestamp IS NULL) OR (CAST(pTimestamp AS date)=CURRENT_DATE)) THEN
    _timestamp := CURRENT_TIMESTAMP;
  ELSE
    _timestamp := pTimestamp;
  END IF;

  IF (pTransType = 'TS' OR pTransType = 'TR') THEN
    SELECT * INTO _t FROM tohead WHERE (tohead_number=pDocNumber);
    IF (pTransType = 'TS') THEN
      _xferwhsid := CASE
          WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
          WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_src_warehous_id
          WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_dest_warehous_id
          WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
          ELSE NULL
          END;
    ELSIF (pTransType = 'TR') THEN
      _xferwhsid := CASE
          WHEN (_t.tohead_src_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
          WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id AND pComments ~* 'recall') THEN _t.tohead_dest_warehous_id
          WHEN (_t.tohead_trns_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_src_warehous_id
          WHEN (_t.tohead_dest_warehous_id=_r.itemsite_warehous_id) THEN _t.tohead_trns_warehous_id
          ELSE NULL
          END;
    END IF;
  END IF;


  -- increase inventory: AD RM RT RP RR RS RX RB TR
  -- decrease inventory: IM IB IT SH SI EX RI
  -- TS and TR are special: shipShipment and recallShipment should not change
  -- QOH at the Transfer Order src whs (as this was done by issueToShipping)
  -- but postReceipt should change QOH at the transit whs
  IF (pTransType='TS') THEN
    _sense := CASE WHEN (SELECT tohead_trns_warehous_id=_r.itemsite_warehous_id
                         FROM tohead
                         WHERE (tohead_number=pDocNumber)) THEN -1
                         ELSE 0
                         END;
  ELSIF (pTransType='TR') THEN
    _sense := CASE WHEN (SELECT tohead_src_warehous_id=_r.itemsite_warehous_id
                         FROM tohead
                         WHERE (tohead_number=pDocNumber)) THEN 0
                         ELSE 1
                         END;
  ELSIF (pTransType IN ('IM', 'IB', 'IT', 'SH', 'SI', 'EX', 'RI')) THEN
    _sense := -1;

  ELSE
    _sense := 1;
  END IF;

  IF((_r.itemsite_costmethod='A') AND (_r.itemsite_qtyonhand + round(_sense * pQty, 6)) < 0) THEN
    -- Can not let average costed itemsites go negative
    RAISE EXCEPTION 'This transaction will cause an Average Costed item to go negative which is not allowed [xtuple: postinvtrans, -2]';
  END IF;

  INSERT INTO invhist
  ( invhist_id, invhist_itemsite_id, invhist_transtype, invhist_transdate,
      invhist_invqty, invhist_qoh_before,
      invhist_qoh_after,
      invhist_costmethod, invhist_value_before, invhist_value_after,
      invhist_ordtype, invhist_ordnumber, invhist_docnumber, invhist_comments,
      invhist_invuom, invhist_unitcost, invhist_xfer_warehous_id, invhist_posted,
      invhist_series )
  SELECT
    _invhistid, itemsite_id, pTransType, _timestamp,
    pQty, itemsite_qtyonhand,
    (itemsite_qtyonhand + (_sense * pQty)),
    itemsite_costmethod, itemsite_value, itemsite_value + (_r.cost * _sense * pQty),
    pOrderType, pOrderNumber, pDocNumber, pComments,
    uom_name, _r.cost, _xferwhsid, FALSE, pItemlocSeries
  FROM itemsite, item, uom
  WHERE ( (itemsite_item_id=item_id)
   AND (item_inv_uom_id=uom_id)
   AND (itemsite_id=pItemsiteid) );

  IF (pCreditid IN (SELECT accnt_id FROM accnt)) THEN
    _creditid = pCreditid;
  ELSE
    SELECT warehous_default_accnt_id INTO _creditid
    FROM itemsite, whsinfo
    WHERE ( (itemsite_warehous_id=warehous_id)
      AND  (itemsite_id=pItemsiteid) );
  END IF;

  IF (pDebitid IN (SELECT accnt_id FROM accnt)) THEN
    _debitid = pDebitid;
  ELSE
    SELECT warehous_default_accnt_id INTO _debitid
    FROM itemsite, whsinfo
    WHERE ( (itemsite_warehous_id=warehous_id)
      AND  (itemsite_id=pItemsiteid) );
  END IF;

  --  Post the G/L Transaction
  IF (_creditid <> _debitid) THEN
    SELECT insertGLTransaction(pModule, pOrderType, pOrderNumber, pComments,
                               _creditid, _debitid, _invhistid,
                               (_r.cost * pQty), _timestamp::DATE, FALSE) INTO _glreturn;
  END IF;

  --  Distribute this if this itemsite is controlled
  IF ( _r.lotserial OR _r.loccntrl ) THEN

    _itemlocdistid := nextval('itemlocdist_itemlocdist_id_seq');
    INSERT INTO itemlocdist
    ( itemlocdist_id,
      itemlocdist_itemsite_id,
      itemlocdist_source_type,
      itemlocdist_reqlotserial,
      itemlocdist_distlotserial,
      itemlocdist_expiration,
      itemlocdist_qty,
      itemlocdist_series,
      itemlocdist_invhist_id,
      itemlocdist_order_type,
      itemlocdist_order_id )
    SELECT _itemlocdistid,
           pItemsiteid,
           'O',
           (((pQty * _sense) > 0)  AND _r.lotserial),
           ((pQty * _sense) < 0),
           endOfTime(),
           (_sense * pQty),
           pItemlocSeries,
           _invhistid,
           pOrderType, 
           CASE WHEN pOrderType='SO' THEN getSalesLineItemId(pOrderNumber)
                ELSE NULL
           END;

    -- populate distributions if invhist_id parameter passed to undo
    IF (pInvhistid IS NOT NULL) THEN
      INSERT INTO itemlocdist
        ( itemlocdist_itemlocdist_id, itemlocdist_source_type, itemlocdist_source_id,
          itemlocdist_itemsite_id, itemlocdist_ls_id, itemlocdist_expiration,
          itemlocdist_qty, itemlocdist_series, itemlocdist_invhist_id ) 
      SELECT _itemlocdistid, 'L', COALESCE(invdetail_location_id, -1),
             invhist_itemsite_id, invdetail_ls_id,  COALESCE(invdetail_expiration, endoftime()),
             (invdetail_qty * -1.0), pItemlocSeries, _invhistid
      FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
      WHERE (invhist_id=pInvhistid);

      IF ( _r.lotserial)  THEN          
        INSERT INTO lsdetail 
          ( lsdetail_itemsite_id, lsdetail_ls_id, lsdetail_created,
            lsdetail_source_type, lsdetail_source_id, lsdetail_source_number ) 
        SELECT invhist_itemsite_id, invdetail_ls_id, CURRENT_TIMESTAMP,
               'I', _itemlocdistid, ''
        FROM invhist JOIN invdetail ON (invdetail_invhist_id=invhist_id)
        WHERE (invhist_id=pInvhistid);
      END IF;

      PERFORM distributeitemlocseries(pItemlocSeries);
      
    END IF;

  END IF;   -- end of distributions

  -- These records will be used for posting G/L transactions to trial balance after records committed.
  -- If we try to do it now concurrency locking prevents any transactions while
  -- user enters item distribution information.  Cant have that.
  INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
  VALUES ( _glreturn, pItemlocSeries );

  RETURN _invhistid;

END;

Function: public.postitemlocseries(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemlocseries ALIAS FOR $1;
  _result INTEGER;

BEGIN

  PERFORM postIntoTrialBalance(itemlocpost_glseq)
  FROM (
    SELECT DISTINCT itemlocpost_glseq, gltrans_accnt_id
    FROM itemlocpost
      JOIN gltrans ON (itemlocpost_glseq=gltrans_sequence)
    WHERE (itemlocpost_itemlocseries=pItemlocseries)
    ORDER BY gltrans_accnt_id
  ) AS data;
  
  PERFORM postInvHist(invhist_id)
  FROM invhist
    JOIN itemsite ON (invhist_itemsite_id=itemsite_id)
  WHERE ( (invhist_series=pItemlocseries)
  AND ( NOT invhist_posted) 
  AND ( NOT itemsite_freeze) );

  DELETE FROM itemlocpost WHERE (itemlocpost_itemlocseries=pItemlocseries);

  RETURN TRUE;
  
END;

Function: public.postjournals(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence	ALIAS FOR $1;
  _transCount INTEGER := 0;
  _journalnumber INTEGER := fetchJournalNumber('J/P');
  _sequence INTEGER := fetchGLSequence();
  _sltrans RECORD;
BEGIN

--  Make sure that we balance
  IF (SELECT SUM(sltrans_amount) != 0
      FROM sltrans
      WHERE ((NOT sltrans_posted )
       AND (sltrans_sequence=pSequence))) THEN
     RAISE EXCEPTION 'Can not post journals. Transactions do not balance in selected date range.';
  END IF;

--  March through the sltrans members, posting them one at a time
  FOR _sltrans IN SELECT sltrans_source, sltrans_accnt_id,
                          SUM(sltrans_amount) as amount
                     FROM sltrans
                    WHERE ((sltrans_amount<>0.0)
                      AND  (NOT sltrans_posted)
                      AND  (sltrans_sequence=pSequence))
                    GROUP BY sltrans_source, sltrans_accnt_id LOOP

-- refuse to accept postings into closed periods
    IF (SELECT BOOL_AND(COALESCE(period_closed, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (CURRENT_DATE BETWEEN period_start AND period_end)
        WHERE (accnt_id = _sltrans.sltrans_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to closed period (%).', _sltrans.sltrans_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

-- refuse to accept postings into frozen periods without proper priv
    IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
               BOOL_AND(COALESCE(period_freeze, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (CURRENT_DATE BETWEEN period_start AND period_end)
        WHERE (accnt_id = _sltrans.sltrans_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to frozen period (%).', _sltrans.sltrans_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

    IF (_sltrans.amount != 0) THEN
       INSERT INTO gltrans
        ( gltrans_posted, gltrans_exported, gltrans_created, gltrans_date,
          gltrans_sequence, gltrans_accnt_id, gltrans_source, gltrans_notes,
          gltrans_doctype, gltrans_docnumber, gltrans_amount, gltrans_journalnumber, gltrans_rec )
        VALUES
        ( FALSE, FALSE, CURRENT_TIMESTAMP, CURRENT_DATE,
          _sequence, _sltrans.sltrans_accnt_id, _sltrans.sltrans_source, 'Journal Posting',
          'JP', _journalnumber, _sltrans.amount, _journalnumber, TRUE );
      
      _transCount := _transCount + 1;
    END IF;
  END LOOP;

--  Update all of the posted sltrans members
  UPDATE sltrans SET
    sltrans_posted=true,
    sltrans_gltrans_journalnumber=_journalnumber
  WHERE ((NOT sltrans_posted)
    AND (sltrans_sequence=pSequence));

  PERFORM postIntoTrialBalance(_sequence);

  RETURN _journalnumber;

END;

Function: public.postjournals(text, date, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource		ALIAS FOR $1;
  pStartDate 		ALIAS FOR $2;
  pEndDate		ALIAS FOR $3;
  pDistDate     	ALIAS FOR $4;
  _transCount INTEGER := 0;
  _journalnumber INTEGER := fetchJournalNumber('J/P');
  _sequence INTEGER := fetchGLSequence();
  _sltrans RECORD;
BEGIN

--  Make sure that we balance
  IF (SELECT SUM(sltrans_amount) != 0
      FROM sltrans
      WHERE ((NOT sltrans_posted )
       AND (sltrans_source=pSource)
       AND (sltrans_date BETWEEN pStartDate AND pEndDate))) THEN
     RAISE EXCEPTION 'Can not post journals. Transactions do not balance in selected date range.';
  END IF;

--  March through the sltrans members, posting them one at a time
  FOR _sltrans IN SELECT sltrans_source, sltrans_accnt_id,
                          SUM(sltrans_amount) as amount
                     FROM sltrans
                    WHERE ((sltrans_amount<>0.0)
                      AND  (NOT sltrans_posted)
                      AND  (sltrans_source=pSource)
                      AND  (sltrans_date BETWEEN pStartDate AND pEndDate))
                    GROUP BY sltrans_source, sltrans_accnt_id LOOP

-- refuse to accept postings into frozen periods if any of the accounts disallow it
    IF (SELECT NOT BOOL_AND(checkPrivilege('PostFrozenPeriod')) AND
               BOOL_AND(COALESCE(period_freeze, FALSE))
        FROM accnt LEFT OUTER JOIN
             period ON (pDistDate BETWEEN period_start AND period_end)
        WHERE (accnt_id = _sltrans.sltrans_accnt_id)) THEN
      RAISE EXCEPTION 'Cannot post to frozen period (%).', _sltrans.sltrans_distdate;
      RETURN -4;        -- remove raise exception when all callers check return code
    END IF;

    IF (_sltrans.amount != 0) THEN
       INSERT INTO gltrans
        ( gltrans_posted, gltrans_exported, gltrans_created, gltrans_date,
          gltrans_sequence, gltrans_accnt_id, gltrans_source, gltrans_notes,
          gltrans_doctype, gltrans_docnumber, gltrans_amount, gltrans_journalnumber )
        VALUES
        ( FALSE, FALSE, CURRENT_TIMESTAMP, pDistDate,
          _sequence, _sltrans.sltrans_accnt_id, _sltrans.sltrans_source, 'Journal Posting',
          'JP', _journalnumber, _sltrans.amount, _journalnumber );
      
      _transCount := _transCount + 1;
    END IF;
  END LOOP;

--  Update all of the posted sltrans members
  UPDATE sltrans SET
    sltrans_posted=true,
    sltrans_gltrans_journalnumber=_journalnumber
  WHERE ((NOT sltrans_posted)
    AND (sltrans_source=pSource)
    AND (sltrans_date BETWEEN pStartDate AND pEndDate));

  PERFORM postIntoTrialBalance(_sequence);

  RETURN _journalnumber;

END;

Function: public.postjournals(text[], date, date, date)

Returns: SET OF integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSources		ALIAS FOR $1;
  pStartDate 		ALIAS FOR $2;
  pEndDate		ALIAS FOR $3;
  pDistDate     	ALIAS FOR $4;
  _i INTEGER;
BEGIN
  FOR _i IN 1..ARRAY_UPPER(pSources,1)
  LOOP
    RETURN NEXT postJournals(pSources[_i], pStartDate, pEndDate, pDistDate);
  END LOOP;
  RETURN;
END;

Function: public.postmessage(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pText ALIAS FOR $2;
  _msgid INTEGER;

BEGIN

  SELECT NEXTVAL('msg_msg_id_seq') INTO _msgid;
  INSERT INTO msg
  (msg_id, msg_posted, msg_scheduled, msg_expires, msg_username, msg_text)
  VALUES
  (_msgid, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, endOfTime(), getEffectiveXtUser(), pText);

  INSERT INTO msguser
  ( msguser_msg_id, msguser_username )
  VALUES
  ( _msgid, pUsername );

  NOTIFY "messagePosted";

  RETURN _msgid;

END;

Function: public.postmessage(timestamp without time zone, timestamp without time zone, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pScheduled ALIAS FOR $1;
  pExpires ALIAS FOR $2;
  pText ALIAS FOR $3;
  _msgid INTEGER;

BEGIN

  SELECT NEXTVAL('msg_msg_id_seq') INTO _msgid;
  INSERT INTO msg
  (msg_id, msg_posted, msg_scheduled, msg_expires, msg_username, msg_text)
  VALUES
  (_msgid, CURRENT_TIMESTAMP, pScheduled, pExpires, getEffectiveXtUser(), pText);

  INSERT INTO msguser
  ( msguser_msg_id, msguser_username )
  SELECT _msgid, usr_username
  FROM usr
  WHERE (usr_username <> getEffectiveXtUser());

  NOTIFY "messagePosted";

  RETURN _msgid;

END;

Function: public.postmessage(timestamp without time zone, timestamp without time zone, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pScheduled ALIAS FOR $1;
  pExpires ALIAS FOR $2;
  pUsername ALIAS FOR $3;
  pText ALIAS FOR $4;
  _msgid INTEGER;

BEGIN

  SELECT NEXTVAL('msg_msg_id_seq') INTO _msgid;
  INSERT INTO msg
  (msg_id, msg_posted, msg_scheduled, msg_expires, msg_username, msg_text)
  VALUES
  (_msgid, CURRENT_TIMESTAMP, pScheduled, pExpires, getEffectiveXtUser(), pText);

  INSERT INTO msguser
  ( msguser_msg_id, msguser_username )
  VALUES
  ( _msgid, pUsername );

  NOTIFY "messagePosted";

  RETURN _msgid;

END;

Function: public.postmisccount(integer, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pComments ALIAS FOR $3;
  _invcntid INTEGER;
  _result INTEGER;

BEGIN

  SELECT invcnt_id INTO _invcntid
  FROM invcnt
  WHERE ( (NOT invcnt_posted)
   AND (invcnt_itemsite_id=pItemsiteid) );

  IF (_invcntid IS NULL) THEN
    _invcntid := NEXTVAL('invcnt_invcnt_id_seq');

    INSERT INTO invcnt
     ( invcnt_id, invcnt_itemsite_id, invcnt_tagdate,
       invcnt_qoh_before, invcnt_qoh_after,
       invcnt_tag_username, invcnt_cntdate, invcnt_cnt_username,
       invcnt_postdate, invcnt_post_username, invcnt_posted,
       invcnt_priority, invcnt_comments )
    SELECT _invcntid, pItemsiteid, now(),
           itemsite_qtyonhand, pQty,
           getEffectiveXtUser(), now(), getEffectiveXtUser(),
           now(), getEffectiveXtUser(), FALSE,
           FALSE, pComments
    FROM itemsite
    WHERE (itemsite_id=pItemsiteid);

    SELECT postCountTag(_invcntid, FALSE) INTO _result;
    IF (_result < 0) THEN
      DELETE FROM invcnt
      WHERE (invcnt_id=_invcntid);
    END IF;

    RETURN _result;
  ELSE
    RETURN -2;
  END IF;

END;

Function: public.postpogltransactions()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  UPDATE gltrans
  SET gltrans_exported=TRUE
  WHERE ( (NOT gltrans_exported)
   AND (gltrans_source='A/P')
   AND (gltrans_doctype IN ('VO')) );

  RETURN TRUE;

END;

Function: public.postporeceipt(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN postReceipt($1, $2);
END;

Function: public.postporeceipts(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN postReceipts('PO', $1, NULL);
END;

Function: public.postporeturncreditmemo(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPorejectId ALIAS FOR $1;

BEGIN
  RETURN postPoReturnCreditMemo(pPorejectId, NULL);
END;

Function: public.postporeturncreditmemo(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPorejectId ALIAS FOR $1;
  pAmount ALIAS FOR $2;
  _p RECORD;
  _a RECORD;
  _itemsiteId INTEGER;
  _docNumber TEXT;
  _sequence INTEGER;
  _journalNumber INTEGER;
  _apopenid INTEGER;
  _exchGainItem NUMERIC;
  _itemAmount_base NUMERIC;
  _itemAmount NUMERIC;
  _glseriesTotal NUMERIC;
  _tmpTotal NUMERIC;
  _test INTEGER;
  _exchDate DATE;
  _tax RECORD;
  _taxAmount NUMERIC := 0;
  _taxAmount_base NUMERIC;
  _apaccntid INTEGER;

BEGIN
--Set things up
  SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
  SELECT fetchGLSequence() INTO _sequence;
  SELECT fetchJournalNumber('AP-MISC') INTO _journalNumber;
  SELECT fetchapmemonumber() INTO _docNumber;
  _glseriesTotal := 0;

--Get poreject data
  SELECT pohead_vend_id, pohead_number, pohead_curr_id, pohead_orderdate, pohead_taxzone_id,
         poitem_id, poitem_itemsite_id,poitem_expcat_id, poitem_taxtype_id,
        itemsite_costcat_id, poreject_qty, poreject_date,
        ('Return of Item ' || COALESCE(item_number,poitem_vend_item_number)
           || ', qty. ' || formatqty(poreject_qty)) AS notes,
        poreject_value AS value,
        currToBase(pohead_curr_id,(poitem_unitprice * poreject_qty),CURRENT_DATE) AS itemAmount_base,
        (poitem_unitprice * poreject_qty) AS itemAmount
        INTO _p
  FROM pohead, poreject, poitem
        LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
        LEFT OUTER JOIN item ON (itemsite_item_id=item_id)
  WHERE ((poreject_poitem_id=poitem_id)
  AND (pohead_id=poitem_pohead_id)
  AND (poreject_id=pPorejectId));

  _itemAmount := _p.itemAmount;
  _itemAmount_base := _p.itemAmount_base;
  IF (pAmount IS NOT NULL) THEN
    _itemAmount := pAmount;
    _itemAmount_base := currToBase(_p.pohead_curr_id, pAmount, CURRENT_DATE);
  END IF;
  

--  Grab the G/L Accounts
  IF (COALESCE(_p.poitem_itemsite_id, -1) = -1) THEN
    SELECT pp.accnt_id AS pp_accnt_id,
           lb.accnt_id AS lb_accnt_id INTO _a
    FROM expcat, accnt AS pp, accnt AS lb
    WHERE ( (expcat_purchprice_accnt_id=pp.accnt_id)
     AND (expcat_liability_accnt_id=lb.accnt_id)
     AND (expcat_id=_p.poitem_expcat_id) );
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Cannot Post Credit Memo due to unassigned G/L Accounts.';
    END IF;
  ELSE
    SELECT pp.accnt_id AS pp_accnt_id,
           lb.accnt_id AS lb_accnt_id INTO _a
    FROM costcat, accnt AS pp, accnt AS lb
    WHERE ( (costcat_purchprice_accnt_id=pp.accnt_id)
     AND (costcat_liability_accnt_id=lb.accnt_id)
     AND (costcat_id=_p.itemsite_costcat_id) );
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Cannot Post Credit Memo due to unassigned G/L Accounts.';
    END IF;
  END IF;

--  AP Open Item record
    INSERT INTO apopen
    ( apopen_id, apopen_username, apopen_journalnumber,
      apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
      apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
      apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_accnt_id, apopen_curr_id,
      apopen_closedate )
    VALUES
    ( _apopenid, getEffectiveXtUser(), _journalNumber,
      _p.pohead_vend_id, _docNumber, 'C', _p.pohead_number,
      CURRENT_DATE, CURRENT_DATE, CURRENT_DATE, -1,
      round(_itemAmount, 2), 0, (round(_itemAmount, 2) <> 0), _p.notes, -1, _p.pohead_curr_id,
      CASE WHEN (round(_itemAmount, 2) = 0) THEN _p.poreject_date END );

-- Taxes
    FOR _tax IN
      SELECT taxdetail_tax_id, sum(taxdetail_tax) AS taxdetail_tax,
        currToBase(_p.pohead_curr_id, round(sum(taxdetail_tax),2), current_date) AS taxbasevalue
      FROM calculateTaxDetail(_p.pohead_taxzone_id, _p.poitem_taxtype_id,
	  		       current_date, _p.pohead_curr_id, 
			       _itemAmount) 
      GROUP BY taxdetail_tax_id
    LOOP
      INSERT INTO apopentax (taxhist_basis,taxhist_percent,taxhist_amount,taxhist_docdate, taxhist_tax_id, taxhist_tax, 
                             taxhist_taxtype_id, taxhist_parent_id, taxhist_journalnumber ) 
      VALUES (0, 0, 0, current_date, _tax.taxdetail_tax_id, _tax.taxdetail_tax, getadjustmenttaxtypeid(), 
              _apopenid, _journalNumber);

      _taxAmount := _taxAmount + _tax.taxdetail_tax;
 
    END LOOP;

    _taxAmount_base := addTaxToGLSeries(_sequence,
		       'A/P', 'CM', _docNumber,
		       _p.pohead_curr_id, current_date, current_date,
                      'apopentax', _apopenid,
                      _p.notes);

    UPDATE apopen SET apopen_amount = round(_itemAmount + _taxAmount,2)
    WHERE (apopen_id = _apopenid);

--  Distribute from the clearing account
    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
                _a.lb_accnt_id,
                round(_p.value, 2),
                current_date, _p.notes );
    _glseriesTotal := _glseriesTotal + round(_p.value, 2);

--  Distribute the remaining variance to the Purchase Price Variance account
    IF (round(_itemAmount_base, 2) <> round(_p.value, 2)) THEN
      _tmpTotal := round(_itemAmount_base, 2) - round(_p.value, 2);
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
                                  _a.pp_accnt_id,
                                  _tmpTotal,
                                  current_date, _p.notes );
        _glseriesTotal := _glseriesTotal + _tmpTotal;
    END IF;

--  Post the reject item for this P/O Item as Invoiced
    UPDATE poreject
    SET poreject_invoiced=TRUE
    WHERE poreject_id=pPorejectId;

--  Update the qty vouchered field
    UPDATE poitem
       SET poitem_qty_vouchered = (poitem_qty_vouchered - _p.poreject_qty)
     WHERE (poitem_id=_p.poitem_id);

--  Post to A/P
  SELECT findAPAccount(_p.pohead_vend_id) INTO _apaccntid;
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Post Credit Memo due to an unassigned A/P Account.';
  END IF;

  SELECT insertIntoGLSeries( _sequence, 'A/P', 'CM', _docNumber,
                             _apaccntid, round(_itemAmount_base + _taxAmount_base, 2) *-1,
                             current_date, _p.notes ) INTO _test;
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Post Credit Memo.';
  END IF;

-- Clean up loose ends

  _glseriesTotal := _glseriesTotal + round(_itemAmount_base, 2)*-1;

  IF (round(_glseriesTotal, 2) != 0) THEN
        PERFORM insertIntoGLSeries(_sequence, 'A/P', 'CM',
            'Currency Exchange Rounding - ' || _docNumber,
            getGainLossAccntId(_apaccntid), round(_glseriesTotal, 2) * -1,
           current_date, _p.notes);
  END IF;

--  Post it all
  PERFORM postGLSeries(_sequence, _journalNumber);

  RETURN _journalNumber;

END;

Function: public.postporeturns(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;
  _itemlocSeries INTEGER;
  _p RECORD;
  _returnval	INTEGER;

BEGIN

  _itemlocSeries := 0;

  SELECT postPoReturns(pPoheadid,false) INTO _itemlocseries;

  RETURN _itemlocSeries;

END;

Function: public.postporeturns(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;
  pCreateMemo ALIAS FOR $2;
  _itemlocSeries INTEGER;
  _p RECORD;
  _returnval	INTEGER;
  _tmp        INTEGER;
  _pricevar   NUMERIC := 0.00;
  _invhistid		INTEGER;
  _journalNumber INTEGER := fetchJournalNumber('GL-MISC');

BEGIN

  _itemlocSeries := 0;

  FOR _p IN SELECT pohead_number, pohead_curr_id, poreject_id, poitem_prj_id,
		   poreject_poitem_id, poitem_id, poitem_expcat_id, poitem_linenumber,
		   currToBase(COALESCE(recv_purchcost_curr_id, pohead_curr_id),
                              COALESCE(recv_purchcost, poitem_unitprice),
			      pohead_orderdate) AS poitem_unitprice_base,
                   COALESCE(itemsite_id, -1) AS itemsiteid, poitem_invvenduomratio,
                   SUM(poreject_qty) AS totalqty,
                   itemsite_item_id, itemsite_costmethod, itemsite_controlmethod, recv_date
            FROM pohead JOIN poitem ON (poitem_pohead_id=pohead_id)
                        JOIN poreject ON (poreject_poitem_id=poitem_id AND NOT poreject_posted) 
                        LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
                        LEFT OUTER JOIN recv ON (recv_id=poreject_recv_id)
            WHERE (pohead_id=pPoheadid)
            GROUP BY poreject_id, pohead_number, poreject_poitem_id, poitem_id, poitem_prj_id,
		     poitem_expcat_id, poitem_linenumber, poitem_unitprice, pohead_curr_id,
		     pohead_orderdate, itemsite_id, poitem_invvenduomratio,
                     itemsite_item_id, itemsite_costmethod, itemsite_controlmethod, recv_date,
                     recv_purchcost_curr_id, recv_purchcost LOOP

    IF (_p.itemsiteid = -1) THEN
        SELECT insertGLTransaction( 'S/R', 'PO', _p.pohead_number, 'Return Non-Inventory to P/O',
                                     expcat_liability_accnt_id, 
                                     getPrjAccntId(_p.poitem_prj_id, expcat_exp_accnt_id), -1,
                                     round(_p.poitem_unitprice_base * _p.totalqty * -1, 2),
				     CURRENT_DATE ) INTO _returnval
        FROM expcat
        WHERE (expcat_id=_p.poitem_expcat_id);

        UPDATE poreject
        SET poreject_posted=TRUE, poreject_value= round(_p.poitem_unitprice_base * _p.totalqty, 2)
        WHERE (poreject_id=_p.poreject_id);

    ELSEIF (_p.itemsite_controlmethod='N') THEN
      SELECT insertGLTransaction('S/R', 'PO', _p.pohead_number, 'Return Non-Controlled Inventory from PO',
                                 costcat_liability_accnt_id,
                                 getPrjAccntId(_p.poitem_prj_id, costcat_exp_accnt_id), -1,
                                 round((_p.poitem_unitprice_base * _p.totalqty * -1), 2),
                                 CURRENT_DATE ) INTO _returnval
      FROM itemsite, costcat
      WHERE((itemsite_costcat_id=costcat_id)
        AND (itemsite_id=_p.itemsiteid));
      IF (_returnval = -3) THEN -- zero value transaction
        _returnval := 0;
      END IF;
      UPDATE poreject
      SET poreject_posted=TRUE, poreject_value= round(_p.poitem_unitprice_base * _p.totalqty, 2)
      WHERE (poreject_id=_p.poreject_id);
    ELSE
      IF (_itemlocSeries = 0) THEN
        SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
      END IF;

      SELECT postInvTrans( itemsite_id, 'RP', (_p.totalqty * _p.poitem_invvenduomratio * -1),
                           'S/R', 'PO', (_p.pohead_number || '-' || _p.poitem_linenumber::TEXT), '', 'Return Inventory to P/O',
                           costcat_asset_accnt_id, costcat_liability_accnt_id, _itemlocSeries, CURRENT_TIMESTAMP) INTO _returnval
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_p.itemsiteid) );

      UPDATE poreject
      SET poreject_posted=TRUE, poreject_value=(invhist_unitcost *_p.totalqty * _p.poitem_invvenduomratio)
      FROM invhist
      WHERE ((poreject_id=_p.poreject_id)
      AND (invhist_id=_returnval));

    END IF;

    IF (_returnval < 0) THEN
      RETURN _returnval;
    END IF;


    UPDATE poitem
    SET poitem_qty_returned=(poitem_qty_returned + _p.totalqty),
	poitem_status='O'
    WHERE (poitem_id=_p.poitem_id);

      IF (fetchMetricBool('RecordPPVonReceipt')) THEN -- If the 'Purchase Price Variance on Receipt' option is true
         _invhistid := _returnval;
         -- Find the difference in the purchase price value expected from the P/O and the value of the transaction
         SELECT ((_p.poitem_unitprice_base * poitem_qty_returned) - (invhist_value_after - invhist_value_before)) INTO _pricevar
         FROM invhist, poitem
         WHERE ((invhist_id = _invhistid)
           AND  (poitem_id=_p.poitem_id));

         -- If difference exists then
         IF (_pricevar <> 0.00) THEN
           -- Record an additional GL Transaction for the purchase price variance
           SELECT insertGLTransaction( _journalNumber,
                'S/R', 'PO', _p.pohead_number,
                                       'Purchase price variance adjusted for P/O ' || _p.pohead_number || ' for item ' || _p.poitem_linenumber::TEXT,
                                       costcat_liability_accnt_id,
                                       getPrjAccntId(_p.poitem_prj_id, costcat_purchprice_accnt_id), -1,
                                       _pricevar,
                                       CURRENT_DATE, false ) INTO _tmp
           FROM itemsite, costcat, poitem
           WHERE ((itemsite_costcat_id=costcat_id)
              AND (itemsite_id=poitem_itemsite_id) );
           IF (NOT FOUND) THEN
             RAISE EXCEPTION 'Could not insert G/L transaction: no cost category found for itemsite_id %',
             _p.itemsiteid;
           ELSIF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
             RETURN _tmp;
           ELSE
             -- Posting to trial balance is deferred to prevent locking
             INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
             VALUES ( _tmp, _itemlocSeries );
           END IF;
         END IF;
       END IF;

    IF (pCreateMemo) THEN
	SELECT postPoReturnCreditMemo(_p.poreject_id) INTO _returnval;
    END IF;

    IF (_returnval < 0) THEN
      RETURN _returnval;
    END IF;

  END LOOP;

  RETURN _itemlocSeries;

END;

Function: public.postproduction(integer, numeric, boolean, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postProduction(INTEGER, NUMERIC, BOOLEAN, BOOLEAN) is deprecated. please use postProduction(INTEGER, NUMERIC, BOOLEAN, INTEGER, TIMESTAMP WITH TIME ZONE) instead';
  RETURN postProduction($1, $2, $3, 0, now());
END;

Function: public.postproduction(integer, numeric, boolean, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postProduction(INTEGER, NUMERIC, BOOLEAN, BOOLEAN, INTEGER) is deprecated. please use postProduction(INTEGER, NUMERIC, BOOLEAN, INTEGER, TIMESTAMP WITH TIME ZONE) instead';
  RETURN postProduction($1, $2, $3, $5, now());
END;

Function: public.postproduction(integer, numeric, boolean, boolean, integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'postProduction(INTEGER, NUMERIC, BOOLEAN, BOOLEAN, INTEGER, TEXT, TEXT) is deprecated. please use postProduction(INTEGER, NUMERIC, BOOLEAN, INTEGER, TIMESTAMP WITH TIME ZONE) instead';
  RETURN postProduction($1, $2, $3, $5, now());
END;

Function: public.postproduction(integer, numeric, boolean, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid          ALIAS FOR $1;
  pQty           ALIAS FOR $2;
  pBackflush     ALIAS FOR $3;
  pItemlocSeries ALIAS FOR $4;
  pGlDistTS      ALIAS FOR $5;
  _test          INTEGER;
  _invhistid     INTEGER;
  _itemlocSeries INTEGER;
  _parentQty     NUMERIC;
  _r             RECORD;
  _sense         TEXT;
  _wipPost       NUMERIC;
  _woNumber      TEXT;
  _ucost         NUMERIC;

BEGIN

  IF (pQty = 0) THEN
    RETURN 0;
  ELSIF (pQty > 0) THEN
    _sense = 'from';
  ELSE
    _sense = 'to';
  END IF;

  IF ( ( SELECT wo_status
         FROM wo
         WHERE (wo_id=pWoid) ) NOT IN  ('R','E','I') ) THEN
    RETURN -1;
  END IF;

--  Make sure that all Component Item Sites exist
  SELECT bomitem_id INTO _test
  FROM wo, bomitem, itemsite
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=bomitem_parent_item_id)
   AND (woEffectiveDate(wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
   AND (wo_id=pWoid)
   AND (bomitem_rev_id=wo_bom_rev_id)
   AND (bomitem_item_id NOT IN
        ( SELECT component.itemsite_item_id
          FROM itemsite AS component, itemsite AS parent
          WHERE ( (wo_itemsite_id=parent.itemsite_id)
           AND (parent.itemsite_item_id=bomitem_parent_item_id)
           AND (bomitem_item_id=component.itemsite_item_id)
           AND (woEffectiveDate(wo_startdate) BETWEEN bomitem_effective AND (bomitem_expires - 1))
           AND (bomitem_rev_id=wo_bom_rev_id)
           AND (component.itemsite_active)
           AND (component.itemsite_warehous_id=parent.itemsite_warehous_id) ) ) ) )
  LIMIT 1;
  IF (FOUND AND pBackflush) THEN
    RETURN -2;
  END IF;

  SELECT formatWoNumber(pWoid) INTO _woNumber;

  SELECT roundQty(item_fractional, pQty) INTO _parentQty
  FROM wo, itemsite, item
  WHERE ((wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (wo_id=pWoid));

--  Create the material receipt transaction
  IF (pItemlocSeries = 0) THEN
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  ELSE
    _itemlocSeries = pItemlocSeries;
  END IF;

  IF (pBackflush) THEN
    FOR _r IN SELECT womatl_id, womatl_qtyiss + 
		     (CASE 
		       WHEN (womatl_qtywipscrap >  ((womatl_qtyfxd + (_parentQty + wo_qtyrcv) * womatl_qtyper) * womatl_scrap)) THEN
                         (womatl_qtyfxd + (_parentQty + wo_qtyrcv) * womatl_qtyper) * womatl_scrap
		       ELSE 
		         womatl_qtywipscrap 
		      END) AS consumed,
		     (womatl_qtyfxd + ((_parentQty + wo_qtyrcv) * womatl_qtyper)) * (1 + womatl_scrap) AS expected
	      FROM womatl, wo, itemsite, item
	      WHERE ((womatl_issuemethod IN ('L', 'M'))
		AND  (womatl_wo_id=pWoid)
		AND  (womatl_wo_id=wo_id)
		AND  (womatl_itemsite_id=itemsite_id)
		AND  (itemsite_item_id=item_id)) LOOP
      -- Don't issue more than should have already been consumed at this point
      IF (pQty > 0) THEN
        IF (noNeg(_r.expected - _r.consumed) > 0) THEN
          SELECT issueWoMaterial(_r.womatl_id, noNeg(_r.expected - _r.consumed), _itemlocSeries, pGlDistTS) INTO _itemlocSeries;
        END IF;
      ELSE
        -- Used by postMiscProduction of disassembly
        SELECT returnWoMaterial(_r.womatl_id, (_r.expected * -1.0), _itemlocSeries, CURRENT_TIMESTAMP) INTO _itemlocSeries;
      END IF;

      UPDATE womatl
      SET womatl_issuemethod='L'
      WHERE ( (womatl_issuemethod='M')
       AND (womatl_id=_r.womatl_id) );

    END LOOP;
  END IF;

  SELECT CASE WHEN (pQty < 0 AND itemsite_costmethod='S') THEN stdcost(itemsite_item_id)
              WHEN (pQty < 0) THEN avgcost(itemsite_id)
              WHEN (wo_cosmethod = 'D') THEN wo_wipvalue
              ELSE  round((wo_wipvalue - (wo_postedvalue / wo_qtyord * (wo_qtyord -
                    CASE WHEN (wo_qtyord < wo_qtyrcv + pQty) THEN wo_qtyord
                         ELSE wo_qtyrcv + pQty
                    END ))),2)
         END INTO _wipPost
  FROM wo
    JOIN itemsite ON (wo_itemsite_id=itemsite_id)
  WHERE (wo_id=pWoid);

  SELECT postInvTrans( itemsite_id, 'RM', _parentQty,
                       'W/O', 'WO', _woNumber, '', ('Receive Inventory ' || item_number || ' ' || _sense || ' Manufacturing'),
                       costcat_asset_accnt_id, getPrjAccntId(wo_prj_id, costcat_wip_accnt_id), _itemlocSeries, pGlDistTS,
                       -- the following is only actually used when the item is average or job costed
                       _wipPost ) INTO _invhistid
  FROM wo, itemsite, item, costcat
  WHERE ( (wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (wo_id=pWoid) );

  IF (pQty < 0 ) THEN
    _wipPost := _wipPost * -1;
  END IF;
  
--  Increase this W/O's received qty decrease its WIP value
  UPDATE wo
  SET wo_qtyrcv = (wo_qtyrcv + _parentQty),
      wo_wipvalue = (wo_wipvalue - (CASE WHEN (itemsite_costmethod IN ('A','J'))
                                               THEN _wipPost
                                         WHEN (itemsite_costmethod='S')
                                               THEN (stdcost(itemsite_item_id) * _parentQty)
                                         ELSE 0.0  END))
  FROM itemsite, item
  WHERE ((wo_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (wo_id=pWoid));

--  ROB Increase this W/O's WIP value for custom costing
  SELECT SUM(itemcost_stdcost * _parentQty) INTO _ucost 
  FROM wo JOIN itemsite ON (itemsite_id=wo_itemsite_id)
          JOIN itemcost ON (itemcost_item_id=itemsite_item_id)
          JOIN costelem ON ((costelem_id=itemcost_costelem_id) AND
                            (costelem_exp_accnt_id IS NOT NULL) AND
                            (NOT costelem_sys))
  WHERE (wo_id=pWoid);

  UPDATE wo
  SET wo_wipvalue = (wo_wipvalue + _ucost)
  WHERE (wo_id=pWoid);

--  ROB Distribute to G/L - create Cost Variance, debit WIP
  PERFORM insertGLTransaction( 'W/O', 'WO', _woNumber,
                               ('Post Other Cost ' || item_number || ' ' || _sense || ' Manufacturing'),
                               getPrjAccntId(wo_prj_id, costelem_exp_accnt_id), 
                               getPrjAccntId(wo_prj_id,costcat_wip_accnt_id), _invhistid,
			       (itemcost_stdcost * _parentQty),
                                pGlDistTS::DATE )
FROM wo, costelem, itemcost, costcat, itemsite, item
WHERE 
  ((wo_id=pWoid) AND
  (wo_itemsite_id=itemsite_id) AND
  (itemsite_item_id=item_id) AND
  (costelem_id = itemcost_costelem_id) AND
  (itemcost_item_id = itemsite_item_id) AND
  (itemsite_costcat_id = costcat_id) AND
  (costelem_exp_accnt_id) IS NOT NULL  AND 
  (costelem_sys = false));
--End


--  Make sure the W/O is at issue status
  UPDATE wo
  SET wo_status='I'
  WHERE (wo_id=pWoid);

  RETURN _itemlocSeries;

END;

Function: public.postreceipt(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2011 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  precvid		ALIAS FOR $1;
  _itemlocSeries	INTEGER := COALESCE($2, 0);
  _freightAccnt		INTEGER;
  _glDate		TIMESTAMP WITH TIME ZONE;
  _o			RECORD;
  _ordertypeabbr	TEXT;
  _r			RECORD;
  _ra			RECORD;
  _recvvalue		NUMERIC := 0;
  _pricevar             NUMERIC := 0.00;
  _tmp			INTEGER;
  _toitemitemid		INTEGER;
  _coheadid		INTEGER;
  _coitemid		INTEGER;
  _linenumber           INTEGER;
  _invhistid		INTEGER;
  _shipheadid		INTEGER;
  _ship               	BOOLEAN;
  _i			RECORD;

BEGIN
  SELECT recv_id, recv_order_type, recv_orderitem_id, recv_qty,
	 round(currToBase(recv_freight_curr_id, recv_freight, recv_date::DATE),
	       2) AS recv_freight_base,
	 recv_freight, recv_freight_curr_id, recv_date, recv_gldistdate,
	 itemsite_id, itemsite_item_id, item_inv_uom_id, itemsite_costmethod,
         itemsite_controlmethod, vend_name, item_number
	 INTO _r
  FROM recv LEFT OUTER JOIN itemsite ON (recv_itemsite_id=itemsite_id)
            LEFT OUTER JOIN item ON (itemsite_item_id=item_id)
            LEFT OUTER JOIN vendinfo ON (recv_vend_id=vend_id)
  WHERE ((recv_id=precvid)
    AND  (NOT recv_posted));

  IF (NOT FOUND) THEN
    IF (_itemlocSeries = 0) THEN
      RETURN -10;
    END IF;
    RETURN _itemlocSeries;

  ELSEIF (_r.recv_qty <= 0) THEN
    RETURN -11;

  ELSIF (_r.recv_order_type ='PO') THEN
    _ordertypeabbr := ('P/O for ' || _r.vend_name || ' for item ' || _r.item_number);

    SELECT pohead_number AS orderhead_number, poitem_id AS orderitem_id,
           poitem_linenumber AS orderitem_linenumber,
	   currToBase(pohead_curr_id,
                      COALESCE(recv_purchcost, poitem_unitprice),
		      recv_date::DATE) AS item_unitprice_base,
	   poitem_invvenduomratio AS invvenduomratio,
	   pohead_orderdate AS orderdate, pohead_dropship,
	   poitem_prj_id AS prj_id INTO _o
    FROM recv, pohead, poitem
    WHERE ((recv_orderitem_id=poitem_id)
      AND  (poitem_pohead_id=pohead_id)
      AND  (NOT recv_posted)
      AND  (recv_id=precvid));
  ELSIF (_r.recv_order_type ='RA') THEN
    _ordertypeabbr := 'R/A for item ' || _r.item_number;
    
    SELECT rahead_id AS orderhead_id, rahead_number AS orderhead_number, raitem_id AS orderitem_id,
           raitem_linenumber AS orderitem_linenumber,
	   currToBase(rahead_curr_id, raitem_unitprice,
		    recv_date::DATE) AS item_unitprice_base,
	   raitem_qty_invuomratio AS invvenduomratio,
	   rahead_authdate AS orderdate,
	   raitem_unitcost AS unitcost,
	   rahead_prj_id AS prj_id INTO _o
    FROM recv, rahead, raitem
    WHERE ((recv_orderitem_id=raitem_id)
      AND  (raitem_rahead_id=rahead_id)
      AND  (NOT recv_posted)
      AND  (recv_id=precvid));
  ELSIF (_r.recv_order_type ='TO') THEN
     _ordertypeabbr := 'T/O for item ' || _r.item_number;

    SELECT tohead_number AS orderhead_number, toitem_id AS orderitem_id,
           toitem_linenumber AS orderitem_linenumber,
	   toitem_stdcost AS item_unitprice_base,
	   1.0 AS invvenduomratio,
	   tohead_orderdate AS orderdate,
	   NULL AS prj_id INTO _o
    FROM recv, tohead, toitem
    WHERE ((recv_orderitem_id=toitem_id)
      AND  (toitem_tohead_id=tohead_id)
      AND  (NOT recv_posted)
      AND  (recv_id=precvid));
  ELSE
    RETURN -13;	-- don't know how to handle this order type
  END IF;

  IF (NOT FOUND) THEN
    IF (_itemlocSeries = 0) THEN
      RETURN -10;
    END IF;
    RETURN _itemlocSeries;
  END IF;

  IF (_itemlocSeries = 0) THEN
    _itemlocSeries := NEXTVAL('itemloc_series_seq');
  ELSEIF (_itemlocSeries < 0) THEN
    RETURN _itemlocSeries;
  END IF;

  _glDate := COALESCE(_r.recv_gldistdate, _r.recv_date);

  IF ( (_r.recv_order_type = 'PO') AND
        (_r.itemsite_id = -1 OR _r.itemsite_id IS NULL OR _r.itemsite_controlmethod = 'N') ) THEN

    IF (_r.itemsite_id IS NOT NULL) THEN
      SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'), 
				  'S/R', _r.recv_order_type, _o.orderhead_number,
	  			  'Receive Non-Controlled Inventory from ' || _ordertypeabbr,
				   costcat_liability_accnt_id,
				   getPrjAccntId(_o.prj_id, costcat_exp_accnt_id), -1,
				   round((_o.item_unitprice_base * _r.recv_qty),2),
				   _glDate::DATE, false ) INTO _tmp
      FROM poitem, itemsite, costcat
      WHERE((poitem_itemsite_id=itemsite_id)
        AND (itemsite_costcat_id=costcat_id)
        AND (poitem_id=_o.orderitem_id));
    ELSE
      SELECT insertGLTransaction(fetchJournalNumber('GL-MISC'),
				  'S/R', _r.recv_order_type, _o.orderhead_number,
	  			  'Receive Non-Inventory from ' || 'P/O for ' || _r.vend_name || ' for ' || expcat_code,
				   expcat_liability_accnt_id,
				   getPrjAccntId(_o.prj_id, expcat_exp_accnt_id), -1,
				   round((_o.item_unitprice_base * _r.recv_qty),2),
				   _glDate::DATE, false ) INTO _tmp
      FROM poitem, expcat
      WHERE((poitem_expcat_id=expcat_id)
        AND (poitem_id=_o.orderitem_id));
    END IF;
      

    IF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
      RETURN _tmp;
    ELSE
      -- Posting to trial balance is deferred to prevent locking
      INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
      VALUES ( _tmp, _itemlocSeries );
      
    END IF;

    SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
				'S/R', _r.recv_order_type, _o.orderhead_number,
				'Receive Non-Inventory Freight from ' || _ordertypeabbr,
				 expcat_liability_accnt_id,
				 getPrjAccntId(_o.prj_id, expcat_freight_accnt_id), -1,
				 _r.recv_freight_base,
				 _glDate::DATE, false ),
	   expcat_freight_accnt_id INTO _tmp, _freightAccnt
    FROM poitem, expcat
    WHERE((poitem_expcat_id=expcat_id)
      AND (poitem_id=_o.orderitem_id));

    IF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
      RETURN _tmp;
    ELSE
      -- Posting to trial balance is deferred to prevent locking
      INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
      VALUES ( _tmp, _itemlocSeries );
    END IF;

    _recvvalue := ROUND((_o.item_unitprice_base * _r.recv_qty),2);

    UPDATE poitem
    SET poitem_qty_received = (poitem_qty_received + _r.recv_qty),
	poitem_freight_received = (poitem_freight_received + _r.recv_freight_base)
    WHERE (poitem_id=_o.orderitem_id);

  ELSEIF ( (_r.recv_order_type = 'RA') AND
           (_r.itemsite_id = -1 OR _r.itemsite_id IS NULL OR _r.itemsite_controlmethod = 'N') ) THEN
    RAISE NOTICE 'itemsite controlmethod is %, cannot post receipt.', _r.itemsite_controlmethod;
    RETURN -14;	-- otherwise how do we get the accounts?

  ELSEIF ( (_r.recv_order_type = 'TO') AND
           (_r.itemsite_id = -1 OR _r.itemsite_id IS NULL) ) THEN
    RAISE NOTICE 'itemsite missing';
    RETURN -14;	-- otherwise how do we get the accounts?

  ELSE	-- not ELSIF: some code is shared between diff order types
    IF (_r.recv_order_type = 'PO') THEN
      SELECT postInvTrans( itemsite_id, 'RP'::TEXT,
			   (_r.recv_qty * _o.invvenduomratio),
			   'S/R'::TEXT,
			   _r.recv_order_type::TEXT, _o.orderhead_number::TEXT || '-' || _o.orderitem_linenumber::TEXT,
			   ''::TEXT,
			   'Receive Inventory from ' || _ordertypeabbr,
			   costcat_asset_accnt_id, costcat_liability_accnt_id,
			   _itemlocSeries,
			   _glDate,
                           round((_o.item_unitprice_base * _r.recv_qty),2) -- always passing this in since it is ignored if it is not average costed item
			   ) INTO _tmp
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );
      IF (NOT FOUND) THEN
	RAISE EXCEPTION 'Could not post inventory transaction: no cost category found for itemsite_id %',
	  _r.itemsite_id;
      ELSIF (_tmp < -1) THEN -- less than -1 because -1 means it is a none controlled item
	IF(_tmp = -3) THEN
	  RETURN -12; -- The GL trans value was 0 which means we likely do not have a std cost
	END IF;
	RETURN _tmp;
      END IF;

      -- If the 'Purchase Price Variance on Receipt' option is true
      IF (fetchMetricBool('RecordPPVonReceipt')) THEN
        _invhistid := _tmp;
        -- Find the difference in the purchase price value expected from the P/O and the value of the transaction
        SELECT ((_o.item_unitprice_base * _r.recv_qty) - (invhist_value_after - invhist_value_before)) INTO _pricevar
        FROM invhist
        WHERE (invhist_id = _invhistid);

        -- If difference exists then
        IF (_pricevar <> 0.00) THEN
          -- Record an additional GL Transaction for the purchase price variance
          SELECT insertGLTransaction( fetchJournalNumber('GL-MISC'),
				       'S/R', _r.recv_order_type, _o.orderhead_number,
                                      'Purchase price variance adjusted for P/O ' || _o.orderhead_number || ' for item ' || _r.item_number,
                                      costcat_liability_accnt_id,
                                      getPrjAccntId(_o.prj_id, costcat_purchprice_accnt_id), -1,
                                      _pricevar,
                                      _glDate::DATE, false ) INTO _tmp
          FROM itemsite, costcat
          WHERE ((itemsite_costcat_id=costcat_id)
             AND (itemsite_id=_r.itemsite_id) );
          IF (NOT FOUND) THEN
            RAISE EXCEPTION 'Could not insert G/L transaction: no cost category found for itemsite_id %',
            _r.itemsite_id;
          ELSIF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
            RETURN _tmp;
          ELSE
            -- Posting to trial balance is deferred to prevent locking
            INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
            VALUES ( _tmp, _itemlocSeries );
          END IF;
        END IF;
      END IF;

      SELECT insertGLTransaction(fetchJournalNumber('GL-MISC'),
				  'S/R', _r.recv_order_type, _o.orderhead_number,
				  'Receive Inventory Freight from ' || _o.orderhead_number || ' for item ' || _r.item_number,
				   costcat_liability_accnt_id,
				   getPrjAccntId(_o.prj_id, costcat_freight_accnt_id), -1,
				   _r.recv_freight_base,
				   _glDate::DATE, false ),
	     costcat_freight_accnt_id INTO _tmp, _freightAccnt
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );
      IF (NOT FOUND) THEN
	RAISE EXCEPTION 'Could not insert G/L transaction: no cost category found for itemsite_id %',
	  _r.itemsite_id;
      ELSIF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
	RETURN _tmp;
      ELSE
          -- Posting to trial balance is deferred to prevent locking
          INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
          VALUES ( _tmp, _itemlocSeries );
      END IF;

      UPDATE poitem
      SET poitem_qty_received = (poitem_qty_received + _r.recv_qty),
	  poitem_freight_received = (poitem_freight_received + _r.recv_freight_base)
      WHERE (poitem_id=_o.orderitem_id);

    ELSIF (_r.recv_order_type = 'RA') THEN
      SELECT rahead.*, raitem.* INTO _ra
	    FROM rahead, raitem
        WHERE ((rahead_id=raitem_rahead_id)
        AND  (raitem_id=_r.recv_orderitem_id));
      SELECT postInvTrans(_r.itemsite_id, 'RR',
			  (_r.recv_qty * _o.invvenduomratio),
			  'S/R',
			  _r.recv_order_type, _ra.rahead_number::TEXT || '-' || _ra.raitem_linenumber::TEXT,
			  '',
			  'Receive Inventory from ' || _ordertypeabbr,
			  costcat_asset_accnt_id,
                          CASE WHEN(COALESCE(_ra.raitem_cos_accnt_id, -1) != -1) THEN 
				 getPrjAccntId(_o.prj_id, _ra.raitem_cos_accnt_id)
				WHEN (_ra.raitem_warranty) THEN 
			         getPrjAccntId(_o.prj_id, resolveCOWAccount(_r.itemsite_id, _ra.rahead_cust_id, _ra.rahead_saletype_id, _ra.rahead_shipzone_id))
			       ELSE getPrjAccntId(_o.prj_id, resolveCORAccount(_r.itemsite_id, _ra.rahead_cust_id, _ra.rahead_saletype_id, _ra.rahead_shipzone_id))
			  END,
			  _itemlocSeries, _glDate, COALESCE(_o.unitcost,stdcost(itemsite_item_id)) * _r.recv_qty * _o.invvenduomratio) INTO _tmp
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );

      IF (NOT FOUND) THEN
	    RAISE EXCEPTION 'Could not post inventory transaction: no cost category found for itemsite_id %', _r.itemsite_id;
      ELSIF (_tmp < -1) THEN -- less than -1 because -1 means it is a none controlled item
	    IF(_tmp = -3) THEN
	    RAISE NOTICE 'The GL trans value was 0 which means we likely do not have a std cost';
	    RETURN -12; -- The GL trans value was 0 which means we likely do not have a std cost
	    END IF;
      RETURN _tmp;
      END IF;

      INSERT INTO rahist (rahist_itemsite_id, rahist_date,
			  rahist_descrip,
			  rahist_qty, rahist_uom_id,
			  rahist_source, rahist_source_id, rahist_rahead_id
	  ) VALUES (_r.itemsite_id, _glDate,
		      'Receive Inventory from ' || _ordertypeabbr,
		      _r.recv_qty * _o.invvenduomratio, _r.item_inv_uom_id,
		      'RR', _r.recv_id, _ra.rahead_id
	          );

      SELECT insertGLTransaction(fetchJournalNumber('GL-MISC'),
				  'S/R', _r.recv_order_type, _o.orderhead_number,
				  'Receive Inventory Freight from ' || _o.orderhead_number || ' for item ' || _r.item_number,
				   costcat_liability_accnt_id,
				   getPrjAccntId(_o.prj_id, costcat_freight_accnt_id), -1,
				   _r.recv_freight_base,
				   _glDate::DATE, false ),
	     costcat_freight_accnt_id INTO _tmp, _freightAccnt
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );
      IF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
	    RETURN _tmp;
      ELSE
        -- Posting to trial balance is deferred to prevent locking
        INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
        VALUES ( _tmp, _itemlocSeries );
      END IF;

      INSERT INTO rahist (rahist_date, rahist_descrip,
			  rahist_source, rahist_source_id,
			  rahist_curr_id, rahist_amount,
			  rahist_rahead_id
	  ) VALUES (_glDate, 'Receive Inventory Freight from ' || _ordertypeabbr,
		  'RR', _r.recv_id, _r.recv_freight_curr_id, _r.recv_freight,
		  _ra.rahead_id
	  );

      UPDATE raitem
      SET raitem_qtyreceived = (raitem_qtyreceived + _r.recv_qty)
      WHERE (raitem_id=_o.orderitem_id);
      
-- Expire date doesn't mean anything once the RA is received 
-- WARNING: INSERTING 'NULL' MIGHT CAUSE PROBLEMS!!
      UPDATE rahead
      SET rahead_expiredate = NULL
      WHERE (rahead_id=_o.orderhead_id);

--  Look for 'ship' lines
    SELECT (count(*) > 0) INTO _ship
    FROM raitem
    WHERE ((raitem_disposition = 'S')
     AND (raitem_new_coitem_id IS NULL)
     AND (raitem_rahead_id=_ra.rahead_id));

--  If receiving a qty on a shippable and upon receipt item, create coitem
      IF ((_ra.rahead_timing='R') AND
          (_ship OR (
          (_ra.raitem_disposition IN ('P','V')) AND
          (_ra.raitem_new_coitem_id IS NULL) AND
          (_ra.raitem_qtyauthorized > 0)))) THEN

          IF (_ra.rahead_new_cohead_id IS NOT NULL) THEN
            _coheadid = _ra.rahead_new_cohead_id;
          ELSE  
--  No header, so create a Sales Order header first.
            SELECT nextval('cohead_cohead_id_seq') INTO _coheadid;

            INSERT INTO cohead (
              cohead_id,cohead_number,cohead_cust_id,cohead_custponumber,
              cohead_origin,cohead_orderdate,cohead_salesrep_id,cohead_terms_id,
              cohead_shipvia,cohead_shipto_id,cohead_shiptoname,
              cohead_shiptoaddress1,cohead_shiptoaddress2,cohead_shiptoaddress3,
              cohead_shiptocity,cohead_shiptostate,cohead_shiptozipcode,
              cohead_shiptocountry,cohead_freight,cohead_shiptophone,
              cohead_shipto_cntct_id, cohead_shipto_cntct_honorific,
              cohead_shipto_cntct_first_name, cohead_shipto_cntct_middle,
              cohead_shipto_cntct_last_name, cohead_shipto_cntct_suffix,
              cohead_shipto_cntct_phone, cohead_shipto_cntct_title,
              cohead_shipto_cntct_fax, cohead_shipto_cntct_email,
              cohead_shipchrg_id, cohead_shipform_id,cohead_billtoname,
              cohead_billtoaddress1,cohead_billtoaddress2,cohead_billtoaddress3,
              cohead_billtocity,cohead_billtostate,cohead_billtozipcode,
              cohead_billtocountry,cohead_misc_accnt_id,cohead_misc_descrip,
              cohead_commission,cohead_holdtype,cohead_prj_id,cohead_shipcomplete,
              cohead_curr_id,cohead_taxzone_id,cohead_saletype_id,cohead_shipzone_id)
            SELECT _coheadid,fetchsonumber(),rahead_cust_id,rahead_custponumber,
              'C',current_date,rahead_salesrep_id,COALESCE(cohead_terms_id,cust_terms_id),
              COALESCE(cohead_shipvia,cust_shipvia),rahead_shipto_id,rahead_shipto_name,
              rahead_shipto_address1,rahead_shipto_address2,rahead_shipto_address3,
              rahead_shipto_city,rahead_shipto_state,rahead_shipto_zipcode,
              rahead_shipto_country,0,COALESCE(cohead_shiptophone,''),
              cntct_id, cntct_honorific,
              cntct_first_name, cntct_middle,
              cntct_last_name, cntct_suffix,
              cntct_phone, cntct_title,
              cntct_fax, cntct_email,
              COALESCE(cohead_shipchrg_id,cust_shipchrg_id),
              COALESCE(cohead_shipform_id,cust_shipform_id),
              rahead_billtoname,rahead_billtoaddress1,rahead_billtoaddress2,rahead_billtoaddress3,
              rahead_billtocity,rahead_billtostate,rahead_billtozip,
              rahead_billtocountry,NULL,'',rahead_commission, 'N', rahead_prj_id,
              COALESCE(cohead_shipcomplete,
                CASE WHEN cust_partialship THEN 
                  false 
                ELSE true
                END),rahead_curr_id,rahead_taxzone_id,rahead_saletype_id,rahead_shipzone_id
            FROM rahead
              JOIN custinfo ON (rahead_cust_id=cust_id)
              LEFT OUTER JOIN cohead ON (rahead_orig_cohead_id=cohead_id)
              LEFT OUTER JOIN shiptoinfo ON (rahead_shipto_id=shipto_id)
              LEFT OUTER JOIN cntct ON (shipto_cntct_id=cntct_id)
            WHERE (rahead_id=_ra.rahead_id);

            UPDATE rahead SET rahead_new_cohead_id=_coheadid WHERE rahead_id=_ra.rahead_id;
            
          END IF;
                  
-- Now enter the line item(s)
        IF (_ra.raitem_disposition IN ('P','V')) AND
           (_ra.raitem_new_coitem_id IS NULL) AND
           (_ra.raitem_qtyauthorized > 0) THEN
           
          SELECT nextval('coitem_coitem_id_seq') INTO _coitemid;

          SELECT COALESCE(MAX(coitem_linenumber),0)+1 INTO _linenumber
          FROM coitem
          WHERE (coitem_cohead_id=_coheadid);
      
          INSERT INTO coitem (
            coitem_id,coitem_cohead_id,coitem_linenumber,coitem_itemsite_id,
            coitem_status,coitem_scheddate,coitem_promdate, coitem_qtyord,
            coitem_unitcost,coitem_price,coitem_custprice,coitem_qtyshipped,
            coitem_order_id,coitem_memo,coitem_qtyreturned,
            coitem_taxtype_id,coitem_qty_uom_id,coitem_qty_invuomratio,
            coitem_price_uom_id,coitem_price_invuomratio,coitem_warranty,
            coitem_cos_accnt_id,coitem_order_type, coitem_custpn)
          SELECT _coitemid,_coheadid,_linenumber,_ra.raitem_coitem_itemsite_id,
              'O',_ra.raitem_scheddate,_ra.raitem_scheddate,_ra.raitem_qtyauthorized,
              stdcost(itemsite_item_id),COALESCE(_ra.raitem_saleprice,0),0,0,
              -1,_ra.raitem_notes,0,
              _ra.raitem_taxtype_id,_ra.raitem_qty_uom_id,_ra.raitem_qty_invuomratio,
              _ra.raitem_price_uom_id,_ra.raitem_price_invuomratio,_ra.raitem_warranty,
              _ra.raitem_cos_accnt_id,
              CASE WHEN itemsite_createwo THEN 'W' ELSE NULL END, _ra.raitem_custpn
          FROM itemsite
          WHERE (itemsite_id=_ra.raitem_coitem_itemsite_id);

          UPDATE raitem SET raitem_new_coitem_id=_coitemid WHERE (raitem_id=_ra.raitem_id);
        END IF;
        
        -- Create items to ship that have no direct relation to receipts.
        IF (_ship) THEN
          FOR _i IN
            SELECT raitem_id FROM raitem
            WHERE ((raitem_rahead_id=_ra.rahead_id)
              AND (raitem_disposition = 'S')
              AND (raitem_new_coitem_id IS NULL))
          LOOP

            SELECT nextval('coitem_coitem_id_seq') INTO _coitemid;

            SELECT COALESCE(MAX(coitem_linenumber),0)+1 INTO _linenumber
              FROM coitem
            WHERE (coitem_cohead_id=_coheadid);
      
            INSERT INTO coitem (
              coitem_id,coitem_cohead_id,coitem_linenumber,coitem_itemsite_id,
              coitem_status,coitem_scheddate,coitem_promdate, coitem_qtyord,
              coitem_unitcost,coitem_price,coitem_custprice,coitem_qtyshipped,
              coitem_order_id,coitem_memo,coitem_qtyreturned,
              coitem_taxtype_id,coitem_qty_uom_id,coitem_qty_invuomratio,
              coitem_price_uom_id,coitem_price_invuomratio,coitem_warranty,
              coitem_cos_accnt_id,coitem_order_type,coitem_custpn)
            SELECT _coitemid,_coheadid,_linenumber,raitem_coitem_itemsite_id,
              'O',raitem_scheddate,raitem_scheddate,raitem_qtyauthorized,
              stdcost(itemsite_item_id),COALESCE(raitem_saleprice,0),0,0,
              -1,raitem_notes,0,
              raitem_taxtype_id,raitem_qty_uom_id,raitem_qty_invuomratio,
              raitem_price_uom_id,raitem_price_invuomratio,raitem_warranty,
              raitem_cos_accnt_id,
              CASE WHEN itemsite_createwo THEN 'W' ELSE NULL END,raitem_custpn
            FROM raitem
              JOIN itemsite ON (itemsite_id=raitem_itemsite_id)
            WHERE (raitem_id=_i.raitem_id);
                        
            UPDATE raitem SET raitem_new_coitem_id=_coitemid WHERE (raitem_id=_i.raitem_id);

          END LOOP;
        END IF;
      END IF;


    ELSIF (_r.recv_order_type = 'TO' AND fetchMetricBool('MultiWhs')) THEN
      SELECT interWarehouseTransfer(toitem_item_id, tohead_trns_warehous_id,
            tohead_dest_warehous_id, _r.recv_qty, 
            'TO', formatToNumber(toitem_id), 'Receive from Transit To Dest Warehouse', _itemlocSeries, _glDate ) INTO _tmp
      FROM tohead, toitem
      WHERE ((tohead_id=toitem_tohead_id)
        AND  (toitem_id=_r.recv_orderitem_id));     

      IF (_tmp < 0) THEN
	    RETURN _tmp;
      END IF;

      SELECT insertGLTransaction(fetchJournalNumber('GL-MISC'), 
				  'S/R', _r.recv_order_type, _o.orderhead_number,
				  'Receive Inventory Freight from ' || _o.orderhead_number || ' for item ' || _r.item_number,
				   costcat_toliability_accnt_id,
				   costcat_freight_accnt_id, -1,
				   _r.recv_freight_base,
				   _glDate::DATE, false ),
	     costcat_freight_accnt_id INTO _tmp, _freightAccnt
      FROM itemsite, costcat
      WHERE ( (itemsite_costcat_id=costcat_id)
       AND (itemsite_id=_r.itemsite_id) );
      IF (_tmp < 0 AND _tmp != -3) THEN -- error but not 0-value transaction
	    RETURN _tmp;
      ELSE
        -- Posting to trial balance is deferred to prevent locking
        INSERT INTO itemlocpost ( itemlocpost_glseq, itemlocpost_itemlocseries)
        VALUES ( _tmp, _itemlocSeries );
      END IF;

      UPDATE toitem
      SET toitem_qty_received = (toitem_qty_received + _r.recv_qty),
	  toitem_freight_received = (toitem_freight_received +
				      currToCurr(_r.recv_freight_curr_id,
						 toitem_freight_curr_id,
						 _r.recv_freight, _glDate::DATE))
      WHERE (toitem_id=_o.orderitem_id);

    END IF;
    IF(_r.itemsite_costmethod='A') THEN
      _recvvalue := ROUND((_o.item_unitprice_base * _r.recv_qty),2);
    ELSIF (fetchMetricBool('RecordPPVonReceipt')) THEN
      _recvvalue := ROUND((_o.item_unitprice_base * _r.recv_qty), 2);
    ELSE
      _recvvalue := ROUND(stdcost(_r.itemsite_item_id) * _r.recv_qty * _o.invvenduomratio, 2);
    END IF;
  END IF;

  UPDATE recv
  SET recv_value=_recvvalue, recv_recvcost=_recvvalue / recv_qty, recv_posted=TRUE, recv_gldistdate=_glDate::DATE
  WHERE (recv_id=precvid);
  
  IF (_r.recv_order_type = 'PO') THEN
    -- If this is a drop-shipped PO, then Issue the item to Shipping and Ship the item
    IF (_o.pohead_dropship = TRUE) THEN

      -- Generate the PoItemDropShipped event
      INSERT INTO evntlog
      ( evntlog_evnttime, evntlog_username, evntlog_evnttype_id,
        evntlog_ordtype, evntlog_ord_id, evntlog_warehous_id, 
        evntlog_number )
      SELECT
        CURRENT_TIMESTAMP, evntnot_username, evnttype_id,
        'P', _o.orderitem_id, evntnot_warehous_id,
        (pohead_number || '-' || poitem_linenumber || ': ' || item_number)
      FROM evntnot JOIN evnttype ON (evntnot_evnttype_id = evnttype_id)
           JOIN itemsite ON (evntnot_warehous_id = itemsite_warehous_id) 
           JOIN item ON (itemsite_item_id = item_id)
           JOIN poitem ON (poitem_itemsite_id = itemsite_id)
           JOIN pohead ON (poitem_pohead_id = pohead_id)
      WHERE( (poitem_id = _o.orderitem_id)
      AND (poitem_duedate <= (CURRENT_DATE + itemsite_eventfence))
      AND (evnttype_name = 'PoItemDropShipped') );

    END IF;
  END IF;
  RETURN _itemlocSeries;

END;

Function: public.postreceipts(text, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  porderid		ALIAS FOR $2;
  _itemlocSeries	INTEGER	:= $3;
  _qtyToRecv		NUMERIC;
  _r			RECORD;

BEGIN

  SELECT SUM(qtyToReceive(pordertype, recv_orderitem_id)) INTO _qtyToRecv
  FROM recv, orderitem
  WHERE ((recv_orderitem_id=orderitem_id)
    AND  (recv_order_type=pordertype)
    AND  (orderitem_orderhead_type=pordertype)
    AND  (orderitem_orderhead_id=porderid));

  IF (_qtyToRecv <= 0) THEN
    RETURN -11;
  END IF;

  IF (_itemlocSeries IS NULL OR _itemlocSeries <= 0) THEN
    _itemlocSeries := NEXTVAL('itemloc_series_seq');
  END IF;

  FOR _r IN SELECT postReceipt(recv_id, _itemlocSeries) AS postResult
	    FROM recv, orderitem
	    WHERE ((recv_orderitem_id=orderitem_id)
	      AND  (orderitem_orderhead_id=porderid)
	      AND  (orderitem_orderhead_type=pordertype)
	      AND  (NOT recv_posted)
-- Check for multiple users receiving the same order
              AND  (recv_trans_usr_name=getEffectiveXtUser())
	      AND  (recv_order_type=pordertype)) LOOP
    IF (_r.postResult < 0 AND _r.postResult != -11) THEN
      RETURN _r.postResult; -- fail on 1st error but ignore lines with qty == 0
    END IF;
  END LOOP;

  RETURN _itemlocSeries;
END;

Function: public.postsogltransactions()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN

  UPDATE gltrans
  SET gltrans_exported=TRUE
  WHERE ( (NOT gltrans_exported)
   AND (gltrans_source='A/R')
   AND (gltrans_doctype IN ('IN', 'CM')) );

  RETURN TRUE;

END;

Function: public.postsoitemproduction(integer, numeric, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemId ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pGlDistTS ALIAS FOR $3;
  _itemlocSeries INTEGER := 0;
  
BEGIN
  --If this cost method is not Job then we are using the wrong function
  IF (NOT EXISTS(SELECT itemsite_costmethod
             FROM coitem,itemsite
             WHERE ((coitem_id=pSoitemId)
                AND (coitem_itemsite_id=itemsite_id)
                AND (itemsite_costmethod = 'J')))) THEN
    RAISE EXCEPTION 'The postSoLineBalanceProduction function may only be used with Job costed item sites';
  END IF;

  IF (pQty > 0) THEN
    SELECT COALESCE(postProduction(wo_id, (pQty * coitem_qty_invuomratio), true, 0, pGlDistTS),-1) INTO _itemlocSeries
    FROM wo, coitem
    WHERE ((wo_ordid=pSoItemid)
     AND (wo_ordtype='S')
     AND (coitem_id=pSoItemid));
    
    UPDATE wo SET wo_status = 'C'
    WHERE ((wo_ordid=pSoItemid)
     AND (wo_ordtype='S')
     AND (wo_qtyrcv >= wo_qtyord));
  END IF;

  RETURN _itemlocSeries;
END;

Function: public.postsoitemproduction(integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemId      ALIAS FOR $1;
  pGlDistTS      ALIAS FOR $2;
  _qty NUMERIC;
  
BEGIN
  -- Issuing all, so determine line balance
  SELECT noNeg( coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned - 
              ( SELECT COALESCE(SUM(shipitem_qty), 0)
                FROM shipitem, shiphead
                WHERE ((shipitem_orderitem_id=coitem_id)
                  AND  (shipitem_shiphead_id=shiphead_id)
                  AND  (NOT shiphead_shipped) ) ) ) INTO _qty
  FROM coitem
  WHERE (coitem_id=pSoitemId);

  RETURN postSoItemProduction($1, _qty, $2);
END;

Function: public.poststandardjournal(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  _returnValue INTEGER;

BEGIN

  SELECT postStandardJournal(pStdjrnlid, pDate, FALSE, fetchGLSequence()) INTO _returnValue;

  RETURN _returnValue;

END;

Function: public.poststandardjournal(integer, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pReverse ALIAS FOR $3;
  _returnValue INTEGER;

BEGIN

  RETURN postStandardJournal(pStdjrnlid, pDate, pReverse, fetchGLSequence());

END;

Function: public.poststandardjournal(integer, date, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pReverse ALIAS FOR $3;
  pGlSequence ALIAS FOR $4;

BEGIN

  INSERT INTO glseries
  ( glseries_sequence, glseries_source, glseries_doctype, glseries_docnumber,
    glseries_notes, glseries_accnt_id, glseries_amount, glseries_distdate )
  SELECT pGlSequence, 'G/L', 'ST', stdjrnl_name,
         stdjrnlitem_notes, stdjrnlitem_accnt_id,
         CASE WHEN (pReverse=TRUE) THEN (stdjrnlitem_amount * -1)
              ELSE stdjrnlitem_amount
         END,
         pDate
  FROM stdjrnlitem, stdjrnl
  WHERE ( (stdjrnlitem_stdjrnl_id=stdjrnl_id)
   AND (stdjrnl_id=pStdjrnlid) );

  RETURN pGlSequence;

END;

Function: public.poststandardjournal(integer, date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pGlSequence ALIAS FOR $3;

BEGIN

  RETURN postStandardJournal(pStdjrnlid, pDate, FALSE, pGLSequence);

END;

Function: public.poststandardjournalgroup(integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlgrpid ALIAS FOR $1;
  pDate ALIAS FOR $2;
BEGIN
  RETURN postStandardJournalGroup(pStdjrnlgrpid, pDate, FALSE);
END;

Function: public.poststandardjournalgroup(integer, date, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStdjrnlgrpid ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pReverse ALIAS FOR $3;
  _r RECORD;
  _glSequence INTEGER := -1;

BEGIN

  FOR _r IN SELECT stdjrnlgrpitem_id, stdjrnlgrpitem_stdjrnl_id
            FROM stdjrnlgrpitem
            WHERE ( (stdjrnlgrpitem_stdjrnlgrp_id=pStdjrnlgrpid)
             AND (CURRENT_DATE BETWEEN stdjrnlgrpitem_effective AND (stdjrnlgrpitem_expires - 1))
             AND ( (stdjrnlgrpitem_toapply = -1)
              OR (stdjrnlgrpitem_toapply > stdjrnlgrpitem_applied) ) ) LOOP

    IF (_glSequence = -1) THEN
      SELECT fetchGLSequence() INTO _glSequence;
    END IF;

    PERFORM postStandardJournal(_r.stdjrnlgrpitem_stdjrnl_id, pDate, pReverse, _glSequence);

    UPDATE stdjrnlgrpitem
    SET stdjrnlgrpitem_applied=(stdjrnlgrpitem_applied + 1)
    WHERE (stdjrnlgrpitem_id=_r.stdjrnlgrpitem_id);

  END LOOP;

  RETURN _glSequence;

END;

Function: public.postvalueintoinvbalance(integer, date, numeric, numeric, numeric, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteId ALIAS FOR $1;
  pDate ALIAS FOR $2;
  pQoh ALIAS FOR $3;
  pNn ALIAS FOR $4;
  pOldCost ALIAS FOR $5;
  pNewCost ALIAS FOR $6;
  _invbalid INTEGER;
  _r RECORD;
  _count INTEGER;
  _valChange NUMERIC;
  _nnvalChange NUMERIC;

BEGIN

--  Grab the costhist record to post
  SELECT period_id INTO _r
  FROM period
  WHERE (pDate BETWEEN period_start AND period_end);

  GET DIAGNOSTICS _count = ROW_COUNT;
  
--  Find an inventory balance to post into
  IF ( _count > 0 ) THEN
--  Try to find an existing invbal
    SELECT invbal_id INTO _invbalid
    FROM invbal
    WHERE ( (invbal_period_id=_r.period_id)
      AND (invbal_itemsite_id=pItemsiteId) );

    GET DIAGNOSTICS _count = ROW_COUNT;
    IF (_count = 0) THEN
      -- Wasn't there, so forward update
      PERFORM forwardUpdateItemsite(pItemsiteId);

      --  Try to find an existing invbal again
      SELECT invbal_id INTO _invbalid
      FROM invbal
      WHERE ( (invbal_period_id=_r.period_id)
        AND (invbal_itemsite_id=pItemsiteId) );

      GET DIAGNOSTICS _count = ROW_COUNT;
      IF (_count = 0) THEN
        RAISE EXCEPTION 'An inventory balance record was not found for updating standard costs';
      END IF;
    END IF;

    _valChange := round((pNewCost - pOldCost) * pQoh, 2);
    _nnvalChange := round((pNewCost - pOldCost) * pNn, 2);
    
--  We found an invbal, update it with the change
    IF (_valChange > 0) THEN
      UPDATE invbal SET 
        invbal_value_in = (invbal_value_in + _valChange)
      WHERE (invbal_id=_invbalid);
    ELSE
      UPDATE invbal SET 
        invbal_value_out = (invbal_value_out - _valChange)
      WHERE (invbal_id=_invbalid);
    END IF;

    IF (_nnvalChange > 0) THEN
      UPDATE invbal SET 
        invbal_nnval_in = (invbal_nnval_in + _nnvalChange)
      WHERE (invbal_id=_invbalid);
    ELSE
      UPDATE invbal SET 
        invbal_nnval_out = (invbal_nnval_out - _nnvalChange)
      WHERE (invbal_id=_invbalid);
    END IF;

    UPDATE invbal SET 
      invbal_value_ending = (invbal_value_beginning + invbal_value_in - invbal_value_out),
      invbal_nnval_ending = (invbal_nnval_beginning + invbal_nnval_in - invbal_nnval_out),
      invbal_dirty=true
    WHERE (invbal_id=_invbalid);  

  ELSE
    RAISE EXCEPTION 'No period exists for date %.', pDate;
  END IF;

  RETURN TRUE;

END;

Function: public.postvoucher(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoheadid ALIAS FOR $1;
  pPostCosts ALIAS FOR $2;

BEGIN
  RETURN postVoucher(pVoheadid, fetchJournalNumber('AP-VO'), pPostCosts);
END;

Function: public.postvoucher(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVoheadid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  pPostCosts ALIAS FOR $3;
  _sequence INTEGER;
  _totalAmount_base NUMERIC;
  _totalAmount NUMERIC;
  _itemAmount_base NUMERIC;
  _itemAmount NUMERIC;
  _totalDiscountableAmount NUMERIC;
  _test INTEGER;
  _a RECORD;
  _d RECORD;
  _g RECORD;
  _p RECORD;
  _r RECORD;
  _costx RECORD;
  _pPostCosts BOOLEAN;
  _pExplain BOOLEAN;
  _pLowLevel BOOLEAN;
  _exchGainFreight NUMERIC;
  _taxBaseValue NUMERIC;
  _firstExchDateFreight	DATE;
  _tmpTotal		NUMERIC;
  _glDate		DATE;

BEGIN

  RAISE DEBUG 'postVoucher(%, %, %)', pVoheadid, pJournalNumber, pPostCosts;

  _pPostCosts := TRUE;
  _totalAmount_base := 0;
  _totalAmount := 0;
  _totalDiscountableAmount := 0;
  SELECT fetchGLSequence() INTO _sequence;

--  Cache Voucher Infomation
  SELECT vohead.*,
	 vend_number || '-' || vend_name || ' ' || vohead_reference
							  AS glnotes,
	 COALESCE(pohead_orderdate, vohead_docdate) AS pohead_orderdate,
	 COALESCE(pohead_curr_id, vohead_curr_id) AS pohead_curr_id INTO _p
  FROM vendinfo, vohead LEFT OUTER JOIN pohead ON (vohead_pohead_id = pohead_id)
  WHERE ( (vohead_id=pVoheadid)
  AND (vend_id=vohead_vend_id) )
  FOR UPDATE OF vohead;

  IF (_p.vohead_posted) THEN
    RAISE EXCEPTION 'Cannot post Voucher #% as it is already posted [xtuple: postVoucher, -10, %]',
			_p.vohead_number, _p.vohead_number;
  END IF;

  _glDate := COALESCE(_p.vohead_gldistdate, _p.vohead_distdate);

--  If the vohead_distdate is NULL, assume that this is a NULL vohead and quietly delete it
  IF (_p.vohead_distdate IS NULL) THEN
    DELETE FROM vohead WHERE vohead_id = pVoheadid;
    RETURN 0;
  END IF;
  IF (_p.vohead_amount <= 0) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% for a negative or zero amount (%) [xtuple: postVoucher, -1, %, %]',
			_p.vohead_number, _p.vohead_amount,
			_p.vohead_number, _p.vohead_amount;
  END IF;

-- there is no currency gain/loss on items, see issue 3892,
-- but there might be on freight, which is first encountered at p/o receipt
  SELECT recv_date::DATE INTO _firstExchDateFreight
      FROM recv
      WHERE (recv_vohead_id = pVoheadid);

  SELECT round(SUM(amount),4) INTO _tmpTotal
  FROM (
  SELECT SUM(vodist_amount) AS amount
    FROM vodist
   WHERE ( (vodist_vohead_id=pVoheadid)
     AND   (vodist_tax_id=-1) )
  UNION ALL
  SELECT SUM(voitem_freight) AS amount
    FROM voitem
   WHERE (voitem_vohead_id=pVoheadid)
  UNION ALL
  SELECT SUM(tax*-1)
  FROM 
    (SELECT round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.vohead_curr_id, round(sum(taxdetail_tax),2), _p.vohead_docdate) AS taxbasevalue
     FROM tax 
     JOIN calculateTaxDetailSummary('VO', pVoheadid, 'T') ON (taxdetail_tax_id=tax_id)
     GROUP BY tax_id, tax_sales_accnt_id
    ) AS taxdata
  ) AS data;

  IF (_tmpTotal IS NULL OR _tmpTotal <= 0) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% with negative or zero distributions (%) [xtuple: postVoucher, -2, %, %]',
			_p.vohead_number, _tmpTotal,
			_p.vohead_number, _tmpTotal;
  END IF;

  IF (_tmpTotal > _p.vohead_amount) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% with distributions greater than the voucher amount (% > %) [xtuple: postVoucher, -3, %, %, %]',
			_p.vohead_number, _tmpTotal, _p.vohead_amount,
			_p.vohead_number, _tmpTotal, _p.vohead_amount;
  END IF;

  IF (_tmpTotal < _p.vohead_amount) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% with distributions less than the voucher amount (% < %) [xtuple: postVoucher, -4, %, %, %]',
			_p.vohead_number, _tmpTotal, _p.vohead_amount,
			_p.vohead_number, _tmpTotal, _p.vohead_amount;
  END IF;

  SELECT DISTINCT poitem_linenumber INTO _test
    FROM vodist, voitem, poitem 
   WHERE ( (vodist_poitem_id=poitem_id)
     AND   (voitem_poitem_id=poitem_id)
     AND   (voitem_vohead_id=vodist_vohead_id)
     AND   ((poitem_qty_received - poitem_qty_vouchered) = 0)
     AND   (vodist_vohead_id=pVoheadid) )
   LIMIT 1;
  IF (FOUND) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% as one or more of the line items have already been fully vouchered. Check P/O Line #% [postVoucher, -6, %, %]',
         _p.vohead_number, _test,
         _p.vohead_number, _test;
  END IF;

--  Start by handling taxes
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.vohead_curr_id, round(sum(taxdetail_tax),2), _p.vohead_docdate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('VO', pVoheadid, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', _p.vohead_number,
                                _r.tax_sales_accnt_id, 
                                _r.taxbasevalue,
                                _glDate, _p.glnotes );

    RAISE DEBUG 'postVoucher: _r.tax=%', _r.tax;

    _totalAmount_base := (_totalAmount_base - _r.taxbasevalue);
    _totalAmount := (_totalAmount - _r.tax);
     
  END LOOP;

-- Update item tax records with posting data
    UPDATE voitemtax SET 
      taxhist_docdate=_p.vohead_docdate,
      taxhist_distdate=_glDate,
      taxhist_curr_id=_p.vohead_curr_id,
      taxhist_curr_rate=curr_rate,
      taxhist_journalnumber=pJournalNumber
    FROM vohead
     JOIN voitem ON (vohead_id=voitem_vohead_id), 
     curr_rate
    WHERE ((vohead_id=pVoheadId)
      AND (taxhist_parent_id=voitem_id)
      AND (_p.vohead_curr_id=curr_id)
      AND (_p.vohead_docdate BETWEEN curr_effective 
                           AND curr_expires) );

-- Update Misc distributions with posting data
    UPDATE voheadtax SET 
      taxhist_docdate=_p.vohead_docdate,
      taxhist_distdate=_glDate,
      taxhist_curr_id=_p.vohead_curr_id,
      taxhist_curr_rate=curr_rate,
      taxhist_journalnumber=pJournalNumber
    FROM curr_rate
    WHERE ((taxhist_parent_id=pVoheadid)
      AND (_p.vohead_curr_id=curr_id)
      AND (_p.vohead_docdate BETWEEN curr_effective 
                           AND curr_expires) );

--  Loop through the vodist records for the passed vohead that
--  are posted against a P/O Item
  FOR _g IN SELECT DISTINCT poitem_id, voitem_id, voitem_qty, poitem_expcat_id,
                            poitem_invvenduomratio, poitem_prj_id,
                            COALESCE(itemsite_id, -1) AS itemsiteid,
                            COALESCE(itemsite_costcat_id, -1) AS costcatid,
                            COALESCE(itemsite_item_id, -1) AS itemsite_item_id,
                            (SELECT SUM(value) 
                             FROM (
                                SELECT SUM(recv_value) AS value
                                FROM recv
                                WHERE (recv_voitem_id=voitem_id)
                             UNION
                                SELECT SUM(poreject_value)*-1 AS value
                                FROM poreject
                                WHERE (poreject_voitem_id=voitem_id)) as data)
                           AS value_base,
			   (poitem_freight_received - poitem_freight_vouchered) /
			       (poitem_qty_received - poitem_qty_vouchered) * voitem_qty AS vouchered_freight,
                            currToBase(_p.pohead_curr_id,
				       (poitem_freight_received - poitem_freight_vouchered) /
				       (poitem_qty_received - poitem_qty_vouchered) * voitem_qty,
				        _firstExchDateFreight ) AS vouchered_freight_base,
			    voitem_freight,
			    currToBase(_p.vohead_curr_id, voitem_freight,
                                       _p.vohead_distdate) AS voitem_freight_base
            FROM vodist, voitem,
                 poitem LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
            WHERE ( (vodist_poitem_id=poitem_id)
             AND (voitem_poitem_id=poitem_id)
             AND (voitem_vohead_id=vodist_vohead_id)
             AND (vodist_vohead_id=pVoheadid)) LOOP

--  Grab the G/L Accounts
    IF (_g.costcatid = -1) THEN
      SELECT getPrjAccntId(_g.poitem_prj_id, pp.accnt_id) AS pp_accnt_id,
             lb.accnt_id AS lb_accnt_id INTO _a
      FROM expcat, accnt AS pp, accnt AS lb
      WHERE ( (expcat_purchprice_accnt_id=pp.accnt_id)
       AND (expcat_liability_accnt_id=lb.accnt_id)
       AND (expcat_id=_g.poitem_expcat_id) );
      IF (NOT FOUND) THEN
        RAISE EXCEPTION 'Cannot Post Voucher #% due to unassigned G/L Accounts [xtuple: postVoucher, -7, %]',
                        _p.vohead_number, _p.vohead_number;
      END IF;
    ELSE
      SELECT getPrjAccntId(_g.poitem_prj_id, costcat_purchprice_accnt_id) AS pp_accnt_id,
             getPrjAccntId(_g.poitem_prj_id, costcat_liability_accnt_id) AS lb_accnt_id,
             getPrjAccntId(_g.poitem_prj_id, costcat_freight_accnt_id) AS freight_accnt_id
      INTO _a
      FROM costcat
      WHERE (costcat_id=_g.costcatid);
      IF (NOT FOUND) THEN
        RAISE EXCEPTION 'Cannot Post Voucher #% due to unassigned G/L Accounts [xtuple: postVoucher, -8, %]',
                        _p.vohead_number, _p.vohead_number;
      END IF;
    END IF;

--  Clear the Item Amount accumulator
    _itemAmount_base := 0;
    _itemAmount := 0;

--  Figure out the total posted value for this line item
    FOR _d IN SELECT vodist_id, vodist_amount, vodist_discountable,
		     _p.vohead_curr_id, vodist_costelem_id,
		     currToBase(_p.vohead_curr_id, vodist_amount,
				_p.vohead_distdate) AS vodist_amount_base
              FROM vodist
              WHERE ( (vodist_vohead_id=pVoheadid)
               AND (vodist_poitem_id=_g.poitem_id) ) LOOP

       _pExplain := FALSE;
       SELECT * INTO _costx
         FROM itemcost
        WHERE ( (itemcost_item_id = _g.itemsite_item_id)
          AND   (itemcost_costelem_id = _d.vodist_costelem_id) );

       IF (FOUND) THEN
         _pExplain := _costx.itemcost_lowlevel;
       END IF;

--  Post the cost to the Actual if requested
--      IF ( (pPostCosts) AND (_d.vodist_costelem_id <> -1) ) THEN
      IF ( (_d.vodist_costelem_id <> -1) AND (_g.itemsite_item_id <> -1) ) THEN
        PERFORM updateCost( _g.itemsite_item_id, _d.vodist_costelem_id,
                            _pExplain, (_d.vodist_amount / (_g.voitem_qty * _g.poitem_invvenduomratio)),
			    _p.vohead_curr_id );
      END IF;

--  Add the Distribution Amount to the Item Amount
      RAISE DEBUG 'postVoucher: _d.vodist_amount=%', _d.vodist_amount;

      _itemAmount_base := _itemAmount_base + ROUND(_d.vodist_amount_base, 2);
      _itemAmount := _itemAmount + _d.vodist_amount;
      IF (_d.vodist_discountable) THEN
        _totalDiscountableAmount := (_totalDiscountableAmount + _d.vodist_amount);
      END IF;

    END LOOP;

--  Distribute from the clearing account
    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
		_a.lb_accnt_id,
		round(_g.value_base + _g.vouchered_freight_base, 2) * -1,
		_glDate, _p.glnotes );


--  Attribute the correct portion to currency gain/loss
    _exchGainFreight := 0;
    SELECT currGain(_p.pohead_curr_id, _g.vouchered_freight,
		    _firstExchDateFreight, _p.vohead_distdate )
		    INTO _exchGainFreight;
    IF (round(_exchGainFreight, 2) <> 0) THEN
	PERFORM insertIntoGLSeries(_sequence, 'A/P', 'VO',
	    text(_p.vohead_number),
	    getGainLossAccntId(_a.lb_accnt_id), round(_exchGainFreight, 2),
	   _glDate, _p.glnotes);
    END IF;

--  Distribute the remaining variance to the Purchase Price Variance account
    IF (round(_itemAmount_base, 2) <> round(_g.value_base, 2)) THEN
      _tmpTotal := round(_itemAmount_base, 2) - round(_g.value_base, 2);
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
			          _a.pp_accnt_id,
			          _tmpTotal * -1,
			          _glDate, _p.glnotes );
    END IF;

--  Distribute the remaining freight variance to the Purchase Price Variance account
    IF (round(_g.voitem_freight_base + _exchGainFreight, 2) <> round(_g.vouchered_freight_base, 2)) THEN
      _tmpTotal := round(_g.voitem_freight_base + _exchGainFreight, 2) - round(_g.vouchered_freight_base, 2);
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
        _a.freight_accnt_id,
	      _tmpTotal * -1,
	      _glDate, _p.glnotes );
    END IF;

--  Add the distribution amount to the total amount to distribute
    RAISE DEBUG 'postVoucher: _itemAmount=%', _itemAmount;

    _totalAmount_base := (_totalAmount_base + _itemAmount_base + _g.voitem_freight_base);
    _totalAmount := (_totalAmount + _itemAmount + _g.voitem_freight);

--  Post all the Tagged Receivings for this P/O Item as Invoiced and
--  record the purchase and receive costs
--  Comment out because recv cost is set at receiving now.
    UPDATE recv
    SET recv_invoiced=TRUE,
	recv_recvcost_curr_id=basecurrid(),
        recv_recvcost=round(_g.value_base / _g.voitem_qty, 2)
    FROM poitem
    WHERE ((recv_orderitem_id=poitem_id)
      AND  (recv_order_type='PO')
      AND  (recv_orderitem_id=_g.poitem_id)
      AND  (recv_vohead_id=pVoheadid) );

--  Post all the Tagged Rejections for this P/O Item as Invoiced
    UPDATE poreject
    SET poreject_invoiced=TRUE
    WHERE ( (poreject_poitem_id=_g.poitem_id)
     AND (poreject_vohead_id=pVoheadid) );

--  Update the qty and freight vouchered fields
    UPDATE poitem
       SET poitem_qty_vouchered = (poitem_qty_vouchered + _g.voitem_qty),
           poitem_freight_vouchered = (poitem_freight_vouchered + _g.vouchered_freight)
     WHERE (poitem_id=_g.poitem_id);

  END LOOP;

--  Loop through the vodist records for the passed vohead that
--  are not posted against a P/O Item
--  Skip the tax distributions
  FOR _d IN SELECT vodist_id, vodist_discountable,
		   currToBase(_p.vohead_curr_id, vodist_amount,
			      _p.vohead_distdate) AS vodist_amount_base,
		   vodist_amount,
		   vodist_accnt_id, vodist_expcat_id
            FROM vodist
            WHERE ( (vodist_vohead_id=pVoheadid)
             AND (vodist_poitem_id=-1)
             AND (vodist_tax_id=-1) ) LOOP

--  Distribute from the misc. account
    IF (_d.vodist_accnt_id = -1) THEN
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
			  expcat_exp_accnt_id,
			  round(_d.vodist_amount_base, 2) * -1,
			  _glDate, _p.glnotes )
         FROM expcat
        WHERE (expcat_id=_d.vodist_expcat_id);
    ELSE
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
			  _d.vodist_accnt_id,
			  round(_d.vodist_amount_base, 2) * -1,
			  _glDate, _p.glnotes );
    END IF;

--  Add the Distribution Amount to the Total Amount
    RAISE DEBUG 'postVoucher: _d.vodist_amount=%', _d.vodist_amount;

    _totalAmount_base := _totalAmount_base + ROUND(_d.vodist_amount_base, 2);
    _totalAmount := _totalAmount + _d.vodist_amount;
    IF (_d.vodist_discountable) THEN
      _totalDiscountableAmount := (_totalDiscountableAmount + _d.vodist_amount);
    END IF;

  END LOOP;

  SELECT insertIntoGLSeries( _sequence, 'A/P', 'VO', text(vohead_number),
                             accnt_id, round(_totalAmount_base, 2),
			     _glDate, _p.glnotes ) INTO _test
  FROM vohead LEFT OUTER JOIN accnt ON (accnt_id=findAPAccount(vohead_vend_id))
  WHERE ( (findAPAccount(vohead_vend_id)=0 OR accnt_id > 0) -- G/L interface might be disabled
    AND (vohead_id=pVoheadid) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Post Voucher #% due to an unassigned A/P Account [xtuple: postVoucher, -9, %]',
                    _p.vohead_number, _p.vohead_number;
  END IF;

  PERFORM postGLSeries(_sequence, pJournalNumber);

--  Create the A/P Open Item
  RAISE DEBUG 'postVoucher: _totalAmount=%, _totalDiscountableAmount=%',
                _totalAmount, _totalDiscountableAmount;

  INSERT INTO apopen
  ( apopen_journalnumber, apopen_docdate, apopen_duedate, apopen_distdate, apopen_open,
    apopen_terms_id, apopen_vend_id, apopen_doctype,
    apopen_docnumber, apopen_invcnumber, apopen_ponumber, apopen_reference,
    apopen_amount, apopen_paid, apopen_notes, apopen_username, apopen_posted,
    apopen_curr_id, apopen_discountable_amount )
-- TODO: 
  SELECT pJournalNumber, vohead_docdate, vohead_duedate, _glDate, TRUE,
         vohead_terms_id, vohead_vend_id, 'V',
         vohead_number, vohead_invcnumber, COALESCE(TEXT(pohead_number), 'Misc.'), vohead_reference,
         round(_totalAmount, 2), 0, '', getEffectiveXtUser(), FALSE,
         vohead_curr_id, round(_totalDiscountableAmount, 2)
  FROM vohead LEFT OUTER JOIN pohead ON (vohead_pohead_id=pohead_id)
  WHERE (vohead_id=pVoheadid);

--  Close all of the P/O Items that should be closed by this Voucher
  UPDATE poitem
  SET poitem_status='C'
  FROM voitem
  WHERE ( (voitem_poitem_id=poitem_id)
   AND (voitem_close)
   AND (voitem_vohead_id=pVoheadid) );

--  Check the P/O items and if they are all closed go ahead
--  and close the P/O head.
  IF ( (SELECT (count(*) < 1)
          FROM vohead, poitem
         WHERE ((vohead_pohead_id=poitem_pohead_id)
           AND  (poitem_status<>'C')
           AND  (vohead_id=pVoheadid) ) ) ) THEN
    PERFORM closePo(vohead_pohead_id)
       FROM vohead
      WHERE (vohead_id=pVoheadid);
  END IF;

--  Set the vohead as posted
  UPDATE vohead
  SET vohead_posted=TRUE, vohead_gldistdate=_glDate
  WHERE (vohead_id=pVoheadid);

  RETURN pJournalNumber;

END;

Function: public.postvouchers(boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPostCosts ALIAS FOR $1;
  _journalNumber INTEGER;

BEGIN

  SELECT fetchJournalNumber('AP-VO') INTO _journalNumber;

  PERFORM postVoucher(vohead_id, _journalNumber, pPostCosts)
  FROM vohead
  WHERE (NOT vohead_posted);

  RETURN _journalNumber;

END;

Function: public.primarykeyfields(text, text)

Returns: text[]

Language: PLPGSQL

Return an array containing the names of the primary key fields of pSchema.pRelation. The first key field is in _result[1].

 
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSchema       ALIAS FOR $1;
  pRelation     ALIAS FOR $2;
  _colname      TEXT;
  _counter      INTEGER := 0;
  _result       TEXT[];

BEGIN
  EXECUTE 'SELECT ARRAY(SELECT attname
                         FROM pg_attribute
                         JOIN pg_class idx ON (attrelid         = idx.oid)
                         JOIN pg_namespace ON (idx.relnamespace = pg_namespace.oid)
                         JOIN pg_index     ON (idx.oid          = indexrelid)
                         JOIN pg_class tab ON (indrelid         = tab.oid)
                        WHERE NOT attisdropped
                          AND nspname = ''' || pSchema || ''' 
                          AND indisprimary
                          AND LOWER(tab.relname) = ''' || pRelation || '''
                       ORDER BY attnum);'
  INTO _result;

  RETURN _result;
END;

Function: public.prj()

Returns: SET OF prj

Language: PLPGSQL

A table function that returns Project results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row prj%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllProjects','ViewAllProjects','MaintainPersonalProjects','ViewPersonalProjects')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM prj
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM prj 
      WHERE getEffectiveXtUser() IN (prj_owner_username, prj_username)
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.prjtask()

Returns: SET OF prjtask

Language: PLPGSQL

A table function that returns Project results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row prjtask%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllProjects','ViewAllProjects','MaintainPersonalProjects','ViewPersonalProjects')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM prjtask
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT prjtask.* FROM prjtask
      JOIN prj ON prj_id=prjtask_prj_id
      WHERE getEffectiveXtUser() IN (prjtask_owner_username,prjtask_username,prj_username,prj_owner_username)
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.purgecreditmemos(date)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCutoffDate ALIAS FOR $1;

BEGIN

  DELETE FROM cmitem
  WHERE (cmitem_id IN ( SELECT cmitem_id
                        FROM cmitem, cmhead
                        WHERE ( (cmitem_cmhead_id=cmhead_id)
                          AND   (cmhead_posted)
                          AND   (cmhead_printed)
                          AND   (cmhead_docdate<=pCutoffDate)
                          AND   (checkCreditMemoSitePrivs(cmhead_id)) ) ) );

  DELETE FROM cmhead
  WHERE ( (cmhead_posted)
    AND   (cmhead_printed)
    AND   (cmhead_docdate<=pCutoffDate)
    AND   (checkCreditMemoSitePrivs(cmhead_id)) );

  RETURN TRUE;

END;

Function: public.purgecrmacctmerge(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pDestid       ALIAS FOR $1;
  _result       INTEGER := 0;
  _tmpcount     INTEGER := 0;
BEGIN
  IF EXISTS(SELECT 1
              FROM crmacctsel
             WHERE crmacctsel_dest_crmacct_id=pDestid) THEN
    DELETE FROM crmacctsel WHERE crmacctsel_dest_crmacct_id = pDestid;
    GET DIAGNOSTICS _result = ROW_COUNT;

  ELSIF EXISTS(SELECT 1
                 FROM mrgundo
                WHERE mrgundo_base_schema='public'
                  AND mrgundo_base_table='crmacct'
                  AND mrgundo_base_id=pDestid) THEN

    DELETE FROM crmacct
     WHERE crmacct_id IN (
              SELECT mrgundo_pkey_id
                FROM mrgundo
               WHERE mrgundo_schema   = 'public'
                 AND mrgundo_table    = 'crmacct'
                 and mrgundo_pkey_col = 'crmacct_id'
                 AND mrgundo_col IS NULL
                 AND mrgundo_base_schema = 'public'
                 AND mrgundo_base_table  = 'crmacct'
                 AND mrgundo_base_id     = pDestid)
        AND crmacct_id != pDestid;
    GET DIAGNOSTICS _result = ROW_COUNT;

    DELETE FROM mrgundo
     WHERE mrgundo_base_schema ='public'
       AND mrgundo_base_table  ='crmacct'
       AND mrgundo_base_id     = pDestid;
    GET DIAGNOSTICS _tmpcount = ROW_COUNT;

    _result := _result + _tmpcount;
  END IF;

  RETURN _result;
END;

Function: public.purgeinvoicerecord(date, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCutoffDate ALIAS FOR $1;
  pInvcheadId ALIAS FOR $2;
  _r RECORD;
  _ra RECORD;
  _raheadid INTEGER;
  _result INTEGER;
  _debug BOOLEAN := FALSE;

BEGIN

-- Purge records where the entire Invoice, Billing, Shipper, Sales Order
-- chain of associated documents are closed and complete

  FOR _r IN
  SELECT invchead_id, cobmisc_id, shiphead_id, ordershipped.cohead_id AS ordship_id, orderinvoiced.cohead_id AS ordinv_id
    FROM invchead LEFT OUTER JOIN invcitem ON (invcitem_invchead_id=invchead_id)
                  LEFT OUTER JOIN cobmisc ON (cobmisc_invcnumber::TEXT=invchead_invcnumber)
                  LEFT OUTER JOIN shipitem ON (shipitem_invcitem_id=invcitem_id)
                  LEFT OUTER JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
                  LEFT OUTER JOIN cohead ordershipped ON (ordershipped.cohead_id=shiphead_order_id)
                  LEFT OUTER JOIN coitem ON (coitem_id=invcitem_coitem_id)
                  LEFT OUTER JOIN cohead orderinvoiced ON (orderinvoiced.cohead_id=coitem_cohead_id)
   WHERE ( (invchead_id = pInvcheadId)
     AND   (invchead_posted)
     AND   (checkInvoiceSitePrivs(invchead_id)) )
  GROUP BY invchead_id, cobmisc_id, shiphead_id, ordship_id, ordinv_id LOOP

-- Check Billing

-- Billing header (cobmisc) must be posted
    SELECT cobmisc_id INTO _result
      FROM cobmisc
     WHERE ( (cobmisc_id=_r.cobmisc_id) AND (NOT cobmisc_posted) );
    IF (FOUND) THEN
      RETURN 'Billing not closed';
    END IF;

-- Billing line items (cobill), associated Invoice line items, and
-- associated Sales Order line items must be closed, posted, and after cutoff date
    SELECT cobill_id INTO _result
      FROM cobill JOIN invcitem ON (invcitem_id=cobill_invcitem_id)
                  JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                     ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
                  JOIN coitem ON ( (coitem_id=cobill_coitem_id) AND
                                   (coitem_status NOT IN ('C', 'X')) )
     WHERE (cobill_cobmisc_id=_r.cobmisc_id);
    IF (FOUND) THEN
      RETURN 'Invoice/Sales Order associated with Billing not closed';
    END IF;

-- Check Shipping

-- Shipping header (shiphead) must be shipped
    SELECT shiphead_id INTO _result
      FROM shiphead
     WHERE ( (shiphead_id=_r.shiphead_id) AND (NOT shiphead_shipped) );
    IF (FOUND) THEN
      RETURN 'Shipper not closed';
    END IF;

-- Shipping line items (shipitem) and associated Sales Order line items
-- must be closed
    SELECT shiphead_id INTO _result
      FROM shiphead, cohead, coitem
     WHERE ( (shiphead_id=_r.shiphead_id)
       AND   ( (shiphead_order_type='SO') AND (shiphead_order_id=cohead_id) )
       AND   (coitem_cohead_id=cohead_id)
       AND   (coitem_status NOT IN ('C', 'X')) );
    IF (FOUND) THEN
      RETURN 'Sales Order associated with Shipper not closed';
    END IF;

-- Shipping line items (shipitem) and associated Invoices must be posted
-- and after cutoff date
    SELECT shiphead_id INTO _result
      FROM shiphead JOIN shipitem ON (shipitem_shiphead_id=shiphead_id)
                    JOIN invcitem ON (invcitem_id=shipitem_invcitem_id)
                    JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                       ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
     WHERE (shiphead_id=_r.shiphead_id);
    IF (FOUND) THEN
      RETURN 'Invoice associated with Shipper not closed';
    END IF;

-- Check Sales Order

-- Sales Order line items (coitem) must be closed
    SELECT cohead_id INTO _result
      FROM cohead JOIN coitem ON ( (coitem_cohead_id=cohead_id) AND
                                   (coitem_status NOT IN ('C', 'X')) )
     WHERE (cohead_id=_r.ordship_id);
    IF (FOUND) THEN
      RETURN 'Shipped Sales Order not closed';
    END IF;
    SELECT cohead_id INTO _result
      FROM cohead JOIN coitem ON ( (coitem_cohead_id=cohead_id) AND
                                   (coitem_status NOT IN ('C', 'X')) )
     WHERE (cohead_id=_r.ordinv_id);
    IF (FOUND) THEN
      RETURN 'Invoiced Sales Order not closed';
    END IF;

    IF (fetchMetricBool('MultiWhs')) THEN
    -- Check Original Return Authorization and cross check to New Sales Order
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON ( (raitem_rahead_id=rahead_id) AND
                                     (raitem_status NOT IN ('C', 'X')) )
                    JOIN coitem ON ( (coitem_id=raitem_new_coitem_id) AND
                                     (coitem_status NOT IN ('C', 'X')) )
                    JOIN invcitem ON (invcitem_coitem_id=coitem_id)
                    JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                       ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
       WHERE (rahead_orig_cohead_id=_r.ordship_id);
      IF (FOUND) THEN
        RETURN 'Shipped Original Return Authorization not closed';
      END IF;
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON ( (raitem_rahead_id=rahead_id) AND
                                     (raitem_status NOT IN ('C', 'X')) )
                    JOIN coitem ON ( (coitem_id=raitem_new_coitem_id) AND
                                     (coitem_status NOT IN ('C', 'X')) )
                    JOIN invcitem ON (invcitem_coitem_id=coitem_id)
                    JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                       ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
       WHERE (rahead_orig_cohead_id=_r.ordinv_id);
      IF (FOUND) THEN
        RETURN 'Invoiced Original Return Authorization not closed';
      END IF;

  -- Check New Return Authorization
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON ( (raitem_rahead_id=rahead_id) AND
                                     (NOT raitem_status IN ('C', 'X')) )
                    JOIN coitem ON ( (coitem_id=raitem_orig_coitem_id) AND
                                     (NOT coitem_status IN ('C', 'X')) )
                    JOIN invcitem ON (invcitem_coitem_id=coitem_id)
                    JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                       ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
       WHERE (rahead_new_cohead_id=_r.ordship_id);
      IF (FOUND) THEN
        RETURN 'Shipped New Return Authorization not closed';
      END IF;
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON ( (raitem_rahead_id=rahead_id) AND
                                     (NOT raitem_status IN ('C', 'X')) )
                    JOIN coitem ON ( (coitem_id=raitem_orig_coitem_id) AND
                                     (NOT coitem_status IN ('C', 'X')) )
                    JOIN invcitem ON (invcitem_coitem_id=coitem_id)
                    JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                       ((NOT invchead_posted) OR (invchead_invcdate > pCutoffDate)) )
       WHERE (rahead_new_cohead_id=_r.ordinv_id);
      IF (FOUND) THEN
        RETURN 'Invoiced New Return Authorization not closed';
      END IF;
    END IF;

-- Check Lot/Serial Registration

    IF (fetchMetricBool('MultiWhs')) THEN
  -- Registration associated with Sales Order must be expired
      SELECT lsreg_id INTO _result
        FROM lsreg
       WHERE ( (lsreg_cohead_id=_r.ordship_id)
         AND   (lsreg_expiredate > CURRENT_DATE) );
      IF (FOUND) THEN
        RETURN 'Shipped Sales Order Lot/Serial Registration not closed';
      END IF;
      SELECT lsreg_id INTO _result
        FROM lsreg
       WHERE ( (lsreg_cohead_id=_r.ordinv_id)
         AND   (lsreg_expiredate > CURRENT_DATE) );
      IF (FOUND) THEN
        RETURN 'Invoiced Sales Order Lot/Serial Registration not closed';
      END IF;

  -- Registration associated with Shipping must be expired
      SELECT lsreg_id INTO _result
        FROM lsreg
       WHERE ( (lsreg_cohead_id=_r.shiphead_id)
         AND   (lsreg_expiredate > CURRENT_DATE) );
      IF (FOUND) THEN
        RETURN 'Shipper Lot/Serial Registration not closed';
      END IF;
    END IF;

    IF (fetchMetricBool('MultiWhs')) THEN
  -- Registration associated with Original Return Authorization must be expired
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON (raitem_rahead_id=rahead_id)
                    JOIN raitemls ON (raitemls_raitem_id=raitem_id)
                    JOIN lsreg ON ( (lsreg_ls_id=raitemls_ls_id) AND
                                    (lsreg_expiredate > CURRENT_DATE) )
       WHERE (rahead_orig_cohead_id=_r.ordship_id);
      IF (FOUND) THEN
        RETURN 'Shipped Original Return Authorization Lot/Serial Registration not closed';
      END IF;
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON (raitem_rahead_id=rahead_id)
                    JOIN raitemls ON (raitemls_raitem_id=raitem_id)
                    JOIN lsreg ON ( (lsreg_ls_id=raitemls_ls_id) AND
                                    (lsreg_expiredate > CURRENT_DATE) )
       WHERE (rahead_orig_cohead_id=_r.ordinv_id);
      IF (FOUND) THEN
        RETURN 'Invoiced Original Return Authorization Lot/Serial Registration not closed';
      END IF;

  -- Registration associated with New Return Authorization must be expired
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON (raitem_rahead_id=rahead_id)
                    JOIN raitemls ON (raitemls_raitem_id=raitem_id)
                    JOIN lsreg ON ( (lsreg_ls_id=raitemls_ls_id) AND
                                    (lsreg_expiredate > CURRENT_DATE) )
       WHERE (rahead_new_cohead_id=_r.ordship_id);
      IF (FOUND) THEN
        RETURN 'Shipped New Return Authorization Lot/Serial Registration not closed';
      END IF;
      SELECT rahead_id INTO _result
        FROM rahead JOIN raitem ON (raitem_rahead_id=rahead_id)
                    JOIN raitemls ON (raitemls_raitem_id=raitem_id)
                    JOIN lsreg ON ( (lsreg_ls_id=raitemls_ls_id) AND
                                    (lsreg_expiredate > CURRENT_DATE) )
       WHERE (rahead_new_cohead_id=_r.ordinv_id);
      IF (FOUND) THEN
        RETURN 'Invoiced New Return Authorization Lot/Serial Registration not closed';
      END IF;
    END IF;

-- Cash Advances associated with Sales Order cannot exist
    SELECT aropenalloc_doc_id INTO _result   
      FROM aropenalloc
     WHERE ((aropenalloc_doctype='S')
       AND  (aropenalloc_doc_id=_r.ordship_id));
    IF (FOUND) THEN
      RETURN 'Shipped Cash Advance not closed';
    END IF;
    SELECT aropenalloc_doc_id INTO _result   
      FROM aropenalloc
     WHERE ((aropenalloc_doctype='S')
       AND  (aropenalloc_doc_id=_r.ordinv_id));
    IF (FOUND) THEN
      RETURN 'Invoiced Cash Advance not closed';
    END IF;

  END LOOP;

-- Everything is OK, delete the chain
  FOR _r IN
  SELECT invchead_id, cobmisc_id, shiphead_id, ordershipped.cohead_id AS ordship_id, orderinvoiced.cohead_id AS ordinv_id
    FROM invchead LEFT OUTER JOIN invcitem ON (invcitem_invchead_id=invchead_id)
                  LEFT OUTER JOIN cobmisc ON (cobmisc_invcnumber::TEXT=invchead_invcnumber)
                  LEFT OUTER JOIN shipitem ON (shipitem_invcitem_id=invcitem_id)
                  LEFT OUTER JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
                  LEFT OUTER JOIN cohead ordershipped ON (ordershipped.cohead_id=shiphead_order_id)
                  LEFT OUTER JOIN coitem ON (coitem_id=invcitem_coitem_id)
                  LEFT OUTER JOIN cohead orderinvoiced ON (orderinvoiced.cohead_id=coitem_cohead_id)
   WHERE ( (invchead_id = pInvcheadId)
     AND   (invchead_posted)
     AND   (checkInvoiceSitePrivs(invchead_id)) )
  GROUP BY invchead_id, cobmisc_id, shiphead_id, ordship_id, ordinv_id LOOP

    IF (fetchMetricBool('MultiWhs')) THEN
      FOR _ra IN
        SELECT rahead_id
        FROM rahead
        WHERE (rahead_orig_cohead_id=_r.ordship_id) LOOP
        IF (_debug) THEN
          RAISE NOTICE 'Deleting Original Return head id %', _ra.rahead_id;
        END IF;
        DELETE FROM raitemls WHERE (raitemls_raitem_id IN (SELECT raitem_id
                                                           FROM raitem
                                                           WHERE (raitem_rahead_id=_ra.rahead_id)));
        DELETE FROM rahist WHERE (rahist_rahead_id=_ra.rahead_id);
        DELETE FROM raitem WHERE (raitem_rahead_id=_ra.rahead_id);
        DELETE FROM rahead WHERE (rahead_id=_ra.rahead_id);
      END LOOP;
      FOR _ra IN
        SELECT rahead_id
        FROM rahead
        WHERE (rahead_orig_cohead_id=_r.ordinv_id) LOOP
        IF (_debug) THEN
          RAISE NOTICE 'Deleting Original Return head id %', _ra.rahead_id;
        END IF;
        DELETE FROM raitemls WHERE (raitemls_raitem_id IN (SELECT raitem_id
                                                           FROM raitem
                                                           WHERE (raitem_rahead_id=_ra.rahead_id)));
        DELETE FROM rahist WHERE (rahist_rahead_id=_ra.rahead_id);
        DELETE FROM raitem WHERE (raitem_rahead_id=_ra.rahead_id);
        DELETE FROM rahead WHERE (rahead_id=_ra.rahead_id);
      END LOOP;

      FOR _ra IN
        SELECT rahead_id
          FROM rahead
         WHERE (rahead_new_cohead_id=_r.ordship_id) LOOP
        IF (_debug) THEN
          RAISE NOTICE 'Deleting New Return head id %', _ra.rahead_id;
        END IF;
        DELETE FROM raitemls WHERE (raitemls_raitem_id IN (SELECT raitem_id
                                                           FROM raitem
                                                           WHERE (raitem_rahead_id=_ra.rahead_id)));
        DELETE FROM rahist WHERE (rahist_rahead_id=_ra.rahead_id);
        DELETE FROM raitem WHERE (raitem_rahead_id=_ra.rahead_id);
        DELETE FROM rahead WHERE (rahead_id=_ra.rahead_id);
      END LOOP;
      FOR _ra IN
        SELECT rahead_id
          FROM rahead
         WHERE (rahead_new_cohead_id=_r.ordinv_id) LOOP
        IF (_debug) THEN
          RAISE NOTICE 'Deleting New Return head id %', _ra.rahead_id;
        END IF;
        DELETE FROM raitemls WHERE (raitemls_raitem_id IN (SELECT raitem_id
                                                           FROM raitem
                                                           WHERE (raitem_rahead_id=_ra.rahead_id)));
        DELETE FROM rahist WHERE (rahist_rahead_id=_ra.rahead_id);
        DELETE FROM raitem WHERE (raitem_rahead_id=_ra.rahead_id);
        DELETE FROM rahead WHERE (rahead_id=_ra.rahead_id);
      END LOOP;
    END IF;

    IF (fetchMetricBool('MultiWhs')) THEN
      IF (_debug) THEN
        RAISE NOTICE 'Deleting Lot/Serial Registrations';
      END IF;
      DELETE FROM lsreg WHERE (lsreg_cohead_id=_r.ordship_id);
      DELETE FROM lsreg WHERE (lsreg_cohead_id=_r.ordinv_id);
      DELETE FROM lsreg WHERE (lsreg_shiphead_id=_r.shiphead_id);
    END IF;

    IF (_debug) THEN
      RAISE NOTICE 'Deleting Shipped Sales Order head id %', _r.ordship_id;
    END IF;
    DELETE FROM payco WHERE (payco_cohead_id=_r.ordship_id);
    DELETE FROM coitem WHERE (coitem_cohead_id=_r.ordship_id);
    DELETE FROM cohead WHERE (cohead_id=_r.ordship_id);

    IF (_debug) THEN
      RAISE NOTICE 'Deleting Sales Order head id %', _r.ordinv_id;
    END IF;
    DELETE FROM payco WHERE (payco_cohead_id=_r.ordinv_id);
    DELETE FROM coitem WHERE (coitem_cohead_id=_r.ordinv_id);
    DELETE FROM cohead WHERE (cohead_id=_r.ordinv_id);

    IF (_debug) THEN
      RAISE NOTICE 'Deleting Ship head id %', _r.shiphead_id;
    END IF;
    DELETE FROM shipitem WHERE (shipitem_shiphead_id=_r.shiphead_id);
    DELETE FROM pack WHERE (pack_shiphead_id=_r.shiphead_id);
    DELETE FROM shiphead WHERE (shiphead_id=_r.shiphead_id);

    IF (_debug) THEN
      RAISE NOTICE 'Deleting Billing head id %', _r.cobmisc_id;
    END IF;
    DELETE FROM cobill WHERE (cobill_cobmisc_id=_r.cobmisc_id);
    DELETE FROM cobmisc WHERE (cobmisc_id=_r.cobmisc_id);
  END LOOP;
  
-- Everything is OK, delete the Invoice
  IF (_debug) THEN
    RAISE NOTICE 'Deleting Invoice head id %', _r.invchead_id;
  END IF;
  DELETE FROM invcitem WHERE (invcitem_invchead_id=_r.invchead_id);
  DELETE FROM invchead WHERE (invchead_id=_r.invchead_id);

  RETURN 'Purged';

END;

Function: public.purgeinvoicerecords(date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCutoffDate ALIAS FOR $1;

BEGIN

-- Remove the shipitem records
  DELETE FROM shipitem
  WHERE (shipitem_invcitem_id IN (SELECT invcitem_id 
                                  FROM invcitem 
                                  WHERE invcitem_invchead_id IN ( SELECT invchead_id
                                     FROM invchead
                                     WHERE ( (invchead_invcdate <= pCutoffDate)
                                     AND   (checkInvoiceSitePrivs(invchead_id))
                                     AND   (invchead_posted) ) ) ) );

-- Remove the cobill and cobmisc records
  DELETE FROM cobill
  WHERE (cobill_cobmisc_id IN ( SELECT cobmisc_id
                                FROM cobmisc, invchead
                                WHERE ( (invchead_invcnumber=cobmisc_invcnumber::TEXT)
                                  AND   (checkInvoiceSitePrivs(invchead_id))
                                  AND   (cobmisc_invcdate <= pCutoffDate)
                                  AND   (cobmisc_posted)) ) );

  DELETE FROM cobmisc
  WHERE ( (checkInvoiceSitePrivs(getInvcheadId(cobmisc_invcnumber::TEXT)))
    AND   (cobmisc_invcdate <= pCutoffDate)
    AND   (cobmisc_posted) );

-- Remove the invchead and invcitem records
  DELETE FROM invcitem
  WHERE (invcitem_invchead_id IN ( SELECT invchead_id
                                   FROM invchead
                                   WHERE ( (invchead_invcdate <= pCutoffDate)
                                     AND   (checkInvoiceSitePrivs(invchead_id))
                                     AND   (invchead_posted) ) ) );

  DELETE FROM invchead
  WHERE ( (invchead_invcdate <= pCutoffDate)
    AND   (checkInvoiceSitePrivs(invchead_id))
    AND   (invchead_posted) );

  RETURN 1;

END;

Function: public.purgepostedcountslips(date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCutoffDate ALIAS FOR $1;
  pWarehousid ALIAS FOR $2;

BEGIN

  IF (pWarehousid = -1) THEN
    DELETE FROM cntslip
    WHERE (cntslip_id IN ( SELECT cntslip_id
                           FROM cntslip, invcnt
                           WHERE ( (cntslip_cnttag_id=invcnt_id)
                            AND (invcnt_posted)
                            AND (cntslip_posted)
                            AND (date(invcnt_postdate) <= pCutoffDate) ) ) );

  ELSE
    DELETE FROM cntslip
    WHERE (cntslip_id IN ( SELECT cntslip_id
                           FROM invcnt, itemsite
                           WHERE ( (cntslip_cnttag_id=invcnt_id)
                            AND (invcnt_posted)
                            AND (cntslip_posted)
                            AND (invcnt_itemsite_id=itemsite_id)
                            AND (date(invcnt_postdate) <= pCutoffDate)
                            AND (itemsite_warehous_id=pWarehousid) ) ) );
  END IF;

  RETURN 1;

END;

Function: public.purgepostedcounttags(date, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCutoffDate ALIAS FOR $1;
  pWarehousid ALIAS FOR $2;

BEGIN

  IF (pWarehousid = -1) THEN
    DELETE FROM cntslip
    WHERE (cntslip_cnttag_id IN ( SELECT invcnt_id
                                  FROM invcnt
                                  WHERE ( (invcnt_posted)
                                   AND (date(invcnt_postdate) <= pCutoffDate) ) ) );

    DELETE FROM invcnt
    WHERE ((invcnt_posted)
     AND (date(invcnt_postdate) <= pCutoffDate));

  ELSE
    DELETE FROM cntslip
    WHERE (cntslip_cnttag_id IN ( SELECT invcnt_id
                                  FROM invcnt, itemsite
                                  WHERE ( (invcnt_posted)
                                   AND (invcnt_itemsite_id=itemsite_id)
                                   AND (date(invcnt_postdate) <= pCutoffDate)
                                   AND (itemsite_warehous_id=pWarehousid) ) ) );

    DELETE FROM invcnt
    WHERE (invcnt_id IN ( SELECT invcnt_id 
                          FROM invcnt, itemsite
                          WHERE ( (invcnt_posted)
                           AND (invcnt_itemsite_id=itemsite_id)
                           AND (date(invcnt_postdate) <= pCutoffDate)
                           AND (itemsite_warehous_id=pWarehousid) ) ) );
  END IF;

  RETURN 1;

END;

Function: public.purgeshipments(date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pcutoff ALIAS FOR $1;
  _r RECORD;

BEGIN

  -- Used for transfer orders shipments (which are never invoiced)
  FOR _r IN SELECT shiphead_id
	      FROM shiphead
	     WHERE ( (shiphead_order_type='TO')
               AND   (shiphead_shipped)
               AND   (shiphead_shipdate <= pcutoff) ) LOOP
    DELETE FROM shipitem WHERE (shipitem_shiphead_id=_r.shiphead_id);
    DELETE FROM shiphead WHERE (shiphead_id=_r.shiphead_id);
  END LOOP;

  RETURN 0;

END;

Function: public.qtyallocated(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN qtyAllocated(pItemsiteid, startOfTime(), pDate);

END;

Function: public.qtyallocated(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;

BEGIN
 
  IF ( SELECT metric_value
	FROM metric
	WHERE ((metric_name = 'MultiWhs')
	AND (metric_value = 't'))) THEN
    IF ( SELECT item_sold
         FROM itemsite, item
         WHERE ((itemsite_item_id=item_id)
         AND (itemsite_id=pItemsiteid)) ) THEN
      RETURN (allocatedForTo(pItemsiteid, pStartDate, pEndDate) +
	      allocatedForWo(pItemsiteid, pStartDate, pEndDate) +
	      allocatedForSo(pItemsiteid, pStartDate, pEndDate));
    ELSE
      RETURN (allocatedForTo(pItemsiteid, pStartDate, pEndDate) +
	      allocatedForWo(pItemsiteid, pStartDate, pEndDate));
    END IF;
  ELSE
    IF ( SELECT item_sold
         FROM itemsite, item
         WHERE ((itemsite_item_id=item_id)
         AND (itemsite_id=pItemsiteid)) ) THEN
      RETURN (allocatedForWo(pItemsiteid, pStartDate, pEndDate) +
	      allocatedForSo(pItemsiteid, pStartDate, pEndDate));
    ELSE
      RETURN (allocatedForWo(pItemsiteid, pStartDate, pEndDate));
    END IF;
  END IF;
END;

Function: public.qtyallocated(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAheaddays ALIAS FOR $2;

BEGIN

  RETURN qtyAllocated(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookAheadDays));

END;

Function: public.qtyatshipping(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN qtyAtShipping('SO', $1);
END;

Function: public.qtyatshipping(text, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN qtyAtShipping($1, $2, 'U');
END;

Function: public.qtyatshipping(text, integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  plineitemid	ALIAS FOR $2;
  pstatus       ALIAS FOR $3;
  _qty NUMERIC  := 0.0;

BEGIN

-- pstatus U=unshipped
--         S=shipped
--         B=both unshipped and shipped

  IF (pordertype NOT IN ('SO', 'TO')) THEN
    RAISE EXCEPTION '% is not a valid order type', pordertype;
  END IF;

  IF (pstatus NOT IN ('U', 'S', 'B')) THEN
    RAISE EXCEPTION '% is not a valid status', pstatus;
  END IF;

  SELECT COALESCE(SUM(shipitem_qty), 0.0) INTO _qty
  FROM shipitem, shiphead
  WHERE ((shipitem_shiphead_id=shiphead_id)
    AND  (shiphead_order_type=pordertype)
    AND  (shipitem_orderitem_id=plineitemid)
    AND  (((shiphead_shipped) AND (pstatus IN ('S', 'B'))) OR ((NOT shiphead_shipped) AND (pstatus IN ('U', 'B'))))  );

  RETURN _qty;

END;

Function: public.qtyavailable(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN ( ( SELECT itemsite_qtyonhand
             FROM itemsite
             WHERE (itemsite_id=pItemsiteid) ) +
           (SELECT qtyOrdered(pItemsiteid, (pDate - CURRENT_DATE))) -
           (SELECT qtyAllocated(pItemsiteid, (pDate - CURRENT_DATE))) );
END;

Function: public.qtyavailable(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAheadDays ALIAS FOR $2;

BEGIN

  RETURN ( ( SELECT itemsite_qtyonhand
             FROM itemsite
             WHERE (itemsite_id=pItemsiteid) ) +
           (SELECT qtyOrdered(pItemsiteid, pLookAheadDays)) -
           (SELECT qtyAllocated(pitemsiteid, pLookAheadDays)) );
END;

Function: public.qtyinshipment(text, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  plineitemid	ALIAS FOR $2;
  pshipheadid   ALIAS FOR $3;
  _qty NUMERIC;

BEGIN

  IF (pordertype NOT IN ('SO', 'TO')) THEN
    RAISE EXCEPTION '% is not a valid order type', pordertype;
  END IF;

  IF (pshipheadid IS NULL) THEN
    RAISE EXCEPTION 'Cannot calculate quantity in a shipment with a NULL shipment';
  END IF;

  SELECT SUM(COALESCE(shipitem_qty, 0.0)) INTO _qty
  FROM shipitem, shiphead
  WHERE ((shipitem_shiphead_id=shiphead_id)
      AND (shiphead_order_type=pordertype)
      AND (shipitem_orderitem_id=plineitemid)
      AND (shiphead_id=pshipheadid));

  IF (NOT FOUND) THEN
    RAISE NOTICE 'Quantity of % item % is 0 because shipment % does not exist.',
                  pordertype, plineitemid, pshipheadid;
  END IF;

  RETURN _qty;

END;

Function: public.qtylocation(integer, integer, date, date, integer, text, integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationId  ALIAS FOR $1;
  pLsId        ALIAS FOR $2;
  pExpiration  ALIAS FOR $3;
  pWarranty    ALIAS FOR $4;
  pItemsiteId  ALIAS FOR $5;
  pOrderType   ALIAS FOR $6;
  pOrderId     ALIAS FOR $7;
  pItemlocdistId ALIAS FOR $8;
  _qty         NUMERIC = 0.0;
  _qtyDist     NUMERIC = 0.0;
  _qtyReserved NUMERIC = 0.0;

BEGIN
-- Summarize itemloc qty for this location/itemsite
  SELECT COALESCE(SUM(itemloc_qty), 0) INTO _qty
    FROM itemloc
   WHERE ( (itemloc_itemsite_id=pItemsiteId)
     AND (itemloc_location_id=pLocationId)
     AND (COALESCE(itemloc_ls_id, -1)=COALESCE(pLsId, itemloc_ls_id, -1))
     AND (COALESCE(itemloc_expiration, endoftime())=COALESCE(pExpiration, itemloc_expiration, endoftime()))
     AND (COALESCE(itemloc_warrpurc, endoftime())=COALESCE(pWarranty, itemloc_warrpurc, endoftime())) );

-- Summarize qty distributed but not yet committed by previous distributions
  SELECT COALESCE(SUM(loc.itemlocdist_qty), 0) INTO _qtyDist
    FROM itemlocdist loc
      JOIN itemlocdist ls ON ((ls.itemlocdist_source_type='O')
			  AND (ls.itemlocdist_id=loc.itemlocdist_itemlocdist_id))
   WHERE ( (ls.itemlocdist_itemsite_id=pItemsiteId)
     AND (loc.itemlocdist_source_type='L')
     AND (loc.itemlocdist_source_id=pLocationId)
     AND (COALESCE(ls.itemlocdist_ls_id, -1)=COALESCE(pLsId, ls.itemlocdist_ls_id, -1))
     AND (COALESCE(ls.itemlocdist_expiration, endoftime())=COALESCE(pExpiration, ls.itemlocdist_expiration, endoftime()))
     AND (COALESCE(ls.itemlocdist_warranty, endoftime())=COALESCE(pWarranty, ls.itemlocdist_warranty, endoftime()))
     AND (ls.itemlocdist_id != pItemlocdistId ) );

-- Summarize itemlocrsrv qty for this location/itemsite
-- that is reserved for a different order
  IF (fetchMetricBool('EnableSOReservationsByLocation')) THEN
    SELECT COALESCE(SUM(itemlocrsrv_qty), 0) INTO _qtyReserved
      FROM itemloc JOIN itemlocrsrv ON ( (itemlocrsrv_itemloc_id=itemloc_id)
                                    AND  ((itemlocrsrv_source <> COALESCE(pOrderType, '')) OR
                                          (itemlocrsrv_source_id <> COALESCE(pOrderId, -1))) )
     WHERE ( (itemloc_itemsite_id=pItemsiteId)
       AND (itemloc_location_id=pLocationId)
       AND (COALESCE(itemloc_ls_id, -1)=COALESCE(pLsId, itemloc_ls_id, -1))
       AND (COALESCE(itemloc_expiration, endoftime())=COALESCE(pExpiration, itemloc_expiration, endoftime()))
       AND (COALESCE(itemloc_warrpurc, endoftime())=COALESCE(pWarranty, itemloc_warrpurc, endoftime())) );
  END IF;

  RETURN (_qty + _qtyDist - _qtyReserved);

END;

Function: public.qtyordered(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN

  RETURN qtyOrdered(pItemsiteid, startOfTime(), pDate);

END;

Function: public.qtyordered(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _itemType TEXT;

BEGIN

  SELECT item_type INTO _itemType
  FROM item, itemsite
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_id=pItemsiteid) );

  IF ( SELECT metric_value
	FROM metric
	WHERE ((metric_name = 'MultiWhs')
	AND (metric_value = 't'))) THEN
    RETURN orderedByPo(pItemsiteid, pStartDate, pEndDate) +
           orderedByWo(pItemsiteid, pStartDate, pEndDate) +
           orderedByTo(pItemsiteid, pStartDate, pEndDate);
  ELSE
    RETURN orderedByPo(pItemsiteid, pStartDate, pEndDate) +
           orderedByWo(pItemsiteid, pStartDate, pEndDate);

  END IF;

END;

Function: public.qtyordered(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookahead ALIAS FOR $2;
  _itemType TEXT;
  _result NUMERIC;

BEGIN

  RETURN qtyOrdered(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookahead));

END;

Function: public.qtypr(integer, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDate ALIAS FOR $2;

BEGIN
  RETURN qtypr(pItemsiteid, startOfTime(), pDate);
END;

Function: public.qtypr(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _prtotal NUMERIC;

BEGIN

SELECT SUM(pr_qtyreq) INTO _prtotal
  FROM pr
  WHERE ((pr_status = 'O')
    AND (pr_itemsite_id=pItemsiteid)
    AND (pr_duedate BETWEEN pStartDate AND pEndDate));

 IF (_prtotal IS NULL) THEN
     RETURN 0.0;
 END IF;

 RETURN _prtotal;

END;

Function: public.qtypr(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookahead ALIAS FOR $2; 

BEGIN
  RETURN qtypr(pItemsiteid, startOfTime(), (CURRENT_DATE + pLookahead));
END;

Function: public.qtytoreceive(text, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  porderitemid	ALIAS FOR $2;
  _qty		NUMERIC;

BEGIN
  IF (pordertype = 'TO' AND NOT fetchMetricBool('MultiWhs')) THEN
    RETURN 0;
  END IF;

  IF (pordertype = 'RA' AND NOT fetchMetricBool('EnableReturnAuth')) THEN
    RETURN 0;
  END IF;

  SELECT SUM(recv_qty) INTO _qty
  FROM recv
  WHERE ((recv_orderitem_id=porderitemid)
    AND  (NOT recv_posted)
    AND  (recv_order_type=pordertype));

  RETURN COALESCE(_qty, 0.0);

END;

Function: public.recallshipment(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN recallShipment($1, CURRENT_TIMESTAMP);
END;

Function: public.recallshipment(integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pshipheadid		ALIAS FOR $1;
  _timestamp		TIMESTAMP WITH TIME ZONE := $2;
  _allInvoiced		BOOLEAN;
  _invoicePosted	BOOLEAN;
  _in                   RECORD;
  _co			RECORD;
  _cobill		RECORD;
  _h			RECORD;
  _result               INTEGER;
  _invhistid		INTEGER;
  _itemlocSeries	INTEGER;
  _qty			NUMERIC;
  _qtyToBill		NUMERIC;
  _shiphead		RECORD;
  _to			RECORD;
  _ti			RECORD;
  _value                NUMERIC;

BEGIN

  IF (_timestamp IS NULL) THEN
    _timestamp := CURRENT_TIMESTAMP;
  END IF;

  SELECT * INTO _shiphead
  FROM shiphead
  WHERE (shiphead_id=pshipheadid);
  IF (NOT FOUND OR NOT _shiphead.shiphead_shipped) THEN
    RETURN -1;
  END IF;

  IF (_shiphead.shiphead_order_type = 'SO') THEN
    SELECT cohead_number AS head_number, cohead_cust_id AS cust_id, cohead_prj_id AS prj_id,
           cohead_saletype_id AS saletype_id, cohead_shipzone_id AS shipzone_id INTO _h
      FROM cohead
     WHERE (cohead_id=_shiphead.shiphead_order_id);
    IF (NOT FOUND) THEN
      RETURN -1;
    END IF;

    SELECT COALESCE(BOOL_AND(shipitem_invoiced), FALSE) INTO _allInvoiced
     FROM cobill, shipitem
    WHERE ((cobill_coitem_id=shipitem_orderitem_id)
      AND  (shipitem_shiphead_id=pshipheadid));

    IF (_allInvoiced AND NOT checkPrivilege('RecallInvoicedShipment')) THEN
      RETURN -2;
    END IF;

    -- Check for any associated posted Invoices
    SELECT COALESCE(BOOL_AND(invchead_posted), FALSE) INTO _invoicePosted
    FROM shipitem JOIN invcitem ON (invcitem_id=shipitem_invcitem_id)
                  JOIN invchead ON (invchead_id=invcitem_invchead_id)
    WHERE (shipitem_shiphead_id=pshipheadid);

    IF (_invoicePosted) THEN
      RETURN -4;
    END IF;

    -- Delete any associated unposted Invoices
    FOR _in IN SELECT DISTINCT invchead_id
                 FROM shipitem JOIN invcitem ON (invcitem_id=shipitem_invcitem_id)
                               JOIN invchead ON ( (invchead_id=invcitem_invchead_id) AND
                                                  (NOT invchead_posted) )
                WHERE (shipitem_shiphead_id=pshipheadid) LOOP
      SELECT deleteInvoice(_in.invchead_id) INTO _result;
      IF (_result < 0) THEN
        RETURN _result;
      END IF;
    END LOOP;

    FOR _co IN SELECT coitem_id, coitem_itemsite_id, coitem_qty_invuomratio, coitem_warranty, coitem_cos_accnt_id,
                   itemsite_controlmethod
                 FROM coitem
                  JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
                WHERE(coitem_id IN (SELECT shipitem_orderitem_id
                                      FROM shipitem, shiphead
                                     WHERE((shipitem_shiphead_id=shiphead_id)
                                       AND (shiphead_shipped)
                                       AND (shiphead_id=pshipheadid)))) FOR UPDATE LOOP

      SELECT SUM(shipitem_qty),SUM(COALESCE(shipitem_value, 0)) INTO _qty, _value
      FROM shipitem
      WHERE ( (shipitem_orderitem_id=_co.coitem_id)
       AND (shipitem_shiphead_id=pshipheadid) );

      UPDATE coitem
      SET coitem_qtyshipped = (coitem_qtyshipped - _qty)
      WHERE (coitem_id=_co.coitem_id);

      _qtyToBill := _qty;
      FOR _cobill IN SELECT cobill_id, cobill_qty
			 FROM cobill, shipitem
			WHERE ((cobill_coitem_id=shipitem_orderitem_id)
			  AND  (shipitem_shiphead_id=pshipheadid)
			  AND  (cobill_coitem_id=_co.coitem_id)) FOR UPDATE LOOP

        IF (noNeg(_cobill.cobill_qty - _qtyToBill) = 0) THEN
          DELETE FROM cobill WHERE (cobill_id=_cobill.cobill_id);
        ELSE
	  UPDATE cobill
	  SET cobill_qty = noNeg(cobill_qty - _qtyToBill)
	  WHERE (cobill_id=_cobill.cobill_id);
	END IF;

	_qtyToBill = _qtyToBill - _cobill.cobill_qty;
	EXIT WHEN (_qtyToBill <= 0.0);
      END LOOP;

  --  Check to see if all of the cobills have been deleted for this cobmisc
      IF (EXISTS(SELECT cobmisc_id
                 FROM cobmisc JOIN cobill ON (cobill_cobmisc_id=cobmisc_id)
                 WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted))) THEN
  --  Lines exist, update the freight
        UPDATE cobmisc SET cobmisc_freight = (cobmisc_freight - _shiphead.shiphead_freight)
        WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted);
      ELSE
  --  No lines exist, delete the cobmisc
        DELETE FROM cobmisc
        WHERE (cobmisc_cohead_id=_shiphead.shiphead_order_id AND NOT cobmisc_posted);
      END IF;

  --  Distribute to G/L, debit Shipping Asset, credit COS
      IF (_co.itemsite_controlmethod != 'N') THEN
        PERFORM insertGLTransaction( 'S/R', _shiphead.shiphead_order_type,
	  			   _h.head_number::TEXT, 'Recall Shipment',
                                   CASE WHEN(COALESCE(_co.coitem_cos_accnt_id, -1) != -1)
                                          THEN getPrjAccntId(_h.prj_id, _co.coitem_cos_accnt_id)
                                        WHEN(_co.coitem_warranty = TRUE)
                                          THEN getPrjAccntId(_h.prj_id, resolveCOWAccount(itemsite_id, _h.cust_id, _h.saletype_id, _h.shipzone_id))
				        ELSE getPrjAccntId(_h.prj_id, resolveCOSAccount(itemsite_id, _h.cust_id, _h.saletype_id, _h.shipzone_id))
                                   END,
                                   getPrjAccntId(_h.prj_id,costcat_shipasset_accnt_id), -1,
				   _value,
				   _timestamp::DATE )
        FROM itemsite, costcat
        WHERE ( (itemsite_costcat_id=costcat_id)
         AND (itemsite_id=_co.coitem_itemsite_id) );
       END IF;

    END LOOP;

-- Kit billing selection
-- Set kit billing qty to zero since kits are shipped complete
    FOR _cobill IN SELECT cobill_id, cobill_qty
                   FROM shipitem JOIN coitem sub ON (sub.coitem_id=shipitem_orderitem_id)
                                 JOIN coitem kit ON (kit.coitem_id <> sub.coitem_id AND
                                                     kit.coitem_cohead_id = sub.coitem_cohead_id AND
                                                     kit.coitem_linenumber = sub.coitem_linenumber AND
                                                     kit.coitem_subnumber = 0)
                                 JOIN cobill ON (cobill_coitem_id=kit.coitem_id)
                   WHERE (shipitem_shiphead_id=pshipheadid)
                     AND (sub.coitem_subnumber > 0)
                   GROUP BY cobill_id, cobill_qty
    LOOP
      UPDATE cobill SET cobill_qty = 0.0
      WHERE (cobill_id=_cobill.cobill_id);
    END LOOP;

  ELSEIF (_shiphead.shiphead_order_type = 'TO') THEN
    SELECT * INTO _to
      FROM tohead
     WHERE (tohead_id=_shiphead.shiphead_order_id);
    IF (NOT FOUND) THEN
      RETURN -1;
    END IF;
    IF (_to.tohead_status = 'C') THEN
      RETURN -6;
    END IF;

    FOR _ti IN SELECT toitem_id, toitem_item_id,
		      toitem_qty_received, toitem_qty_ordered, SUM(shipitem_qty) AS qty
	      FROM toitem, shipitem
	      WHERE ((toitem_id=shipitem_orderitem_id)
		AND  (shipitem_shiphead_id=pshipheadid))
	      GROUP BY toitem_id, toitem_item_id,
		       toitem_qty_received, toitem_qty_ordered LOOP

      _itemlocSeries := NEXTVAL('itemloc_series_seq');
      
      SELECT postInvTrans(si.itemsite_id, 'TS', (_ti.qty * -1.0), 'I/M',
			  _shiphead.shiphead_order_type, formatToNumber(_ti.toitem_id),
			  _to.tohead_number,
			  'Recall Shipment from Transit To Src Warehouse',
			  sc.costcat_asset_accnt_id,
			  tc.costcat_shipasset_accnt_id,
			  _itemlocSeries, _timestamp) INTO _invhistid
      FROM itemsite AS ti, costcat AS tc,
	   itemsite AS si, costcat AS sc
      WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
        AND  (si.itemsite_costcat_id=sc.costcat_id)
        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
        AND  (si.itemsite_item_id=_ti.toitem_item_id)
        AND  (ti.itemsite_warehous_id=_to.tohead_src_warehous_id)
        AND  (si.itemsite_warehous_id=_to.tohead_trns_warehous_id) );

      IF (_invhistid < 0) THEN
	RETURN _invhistid;
      END IF;

      -- post the inventory history if lot/serial or location control
      PERFORM postItemlocseries(_itemlocSeries);

      -- record inventory history and qoh changes at transit warehouse but
      -- there is only one g/l account to touch
      SELECT postInvTrans(ti.itemsite_id, 'TR', (_ti.qty * -1.0), 'I/M',
			  _shiphead.shiphead_order_type, formatToNumber(_ti.toitem_id),
			  _to.tohead_number,
			  'Recall Shipment from Transit To Src Warehouse',
			  tc.costcat_asset_accnt_id,
			  tc.costcat_asset_accnt_id,
			  _itemlocSeries, _timestamp,
			  (invhist_invqty * invhist_unitcost)) INTO _invhistid
      FROM itemsite AS ti, costcat AS tc, invhist
      WHERE ((ti.itemsite_costcat_id=tc.costcat_id)
        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id)
        AND  (invhist_id=_invhistid));

      IF (_invhistid < 0) THEN
	RETURN _invhistid;
      END IF;

      -- post the inventory history if lot/serial or location control
      PERFORM postItemlocseries(_itemlocSeries);

      UPDATE toitem
      SET toitem_qty_shipped = (toitem_qty_shipped - _ti.qty)
      WHERE (toitem_id=_ti.toitem_id);

      UPDATE shipitem SET shipitem_shipdate=NULL, shipitem_shipped=FALSE
      WHERE ((shipitem_orderitem_id=_ti.toitem_id)
        AND  (shipitem_shiphead_id=pshipheadid));

      DELETE FROM recv
	WHERE ((recv_orderitem_id=_ti.toitem_id)
	  AND  (recv_order_type='TO')
	  AND  (NOT recv_posted));

    END LOOP;

  END IF;

  UPDATE shiphead
  SET shiphead_shipped=FALSE
  WHERE (shiphead_id=pshipheadid);

  RETURN _itemlocSeries;

END;

Function: public.recallwo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  recallChildren ALIAS FOR $2;
  returnCode INTEGER;

BEGIN

  UPDATE wo
  SET wo_status='E'
  WHERE ((wo_status='R')
   AND (wo_id=pWoid));

  IF (recallChildren) THEN
    returnCode := (SELECT MAX(recallWo(wo_id, TRUE))
                   FROM wo
                   WHERE ((wo_ordtype='W')
                    AND (wo_ordid=pWoid)));
  END IF;

  RETURN 0;
END;

Function: public.receipts(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;

BEGIN
  IF (pTransType IN ('RM', 'RB', 'RT', 'RP', 'RR', 'RX', 'TR')) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.releaseapmemonumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('APMemoNumber', $1::INTEGER) > 0;

Function: public.releasearmemonumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  select releaseNumber('ARMemoNumber', $1::INTEGER) > 0;

Function: public.releasecashrcptnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('CashRcptNumber', $1) > 0;

Function: public.releasecmnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('CmNumber', $1) > 0;

Function: public.releasecmnumber(text)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('CmNumber', $1::INTEGER) > 0;

Function: public.releasecrmaccountnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('CRMAccountNumber', $1::INTEGER) > 0;

Function: public.releaseincidentnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('IncidentNumber', $1) = 1;

Function: public.releaseinvcnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('InvcNumber', $1) > 0;

Function: public.releaseinvcnumber(text)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('InvcNumber', $1::INTEGER) > 0;

Function: public.releasenumber(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  psequence	ALIAS FOR $1;
  pnumber 	ALIAS FOR $2;
BEGIN
  -- drop the number back into the pool if it was not committed
  PERFORM clearNumberIssue(psequence, pnumber);
  
  UPDATE orderseq SET
    orderseq_number = LEAST(pnumber, orderseq_number)
  WHERE (orderseq_name=psequence);

  RETURN 1;
END;

Function: public.releaseponumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('PoNumber', $1) > 0;

Function: public.releaseponumber(text)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('PoNumber', $1::INTEGER) > 0;

Function: public.releaseprnumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('PrNumber', $1) > 0;

Function: public.releasepurchaseorder(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPoheadid ALIAS FOR $1;

BEGIN

  IF ( ( SELECT (COUNT(*) = 0)
         FROM poitem
         WHERE ( (poitem_pohead_id=pPoheadid)
           AND   (poitem_status='U') ) ) ) THEN
    RETURN -1;
  END IF;

  IF ( ( SELECT (pohead_status='U')
         FROM pohead
         WHERE (pohead_id=pPoheadid) ) ) THEN

    --update status and store the date that the order was released on
    UPDATE pohead
    SET pohead_status='O', pohead_released = current_date
    WHERE (pohead_id=pPoheadid);

  END IF;

  --update status and store the duedates at release
  UPDATE poitem
  SET poitem_status='O', poitem_rlsd_duedate = poitem_duedate
  WHERE (poitem_pohead_id=pPoheadid);

  RETURN 1;

END;

Function: public.releasequnumber(integer)

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('QuNumber', $1);

Function: public.releasequnumber(text)

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('QuNumber', $1::INTEGER);

Function: public.releaseshipmentnumber(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _test INTEGER;

BEGIN

--  Check to see if a Shipment exists with the passed number
  SELECT shiphead_id INTO _test
  FROM shiphead
  WHERE (shiphead_number=pNumber);

  IF (FOUND) THEN
    RETURN FALSE;
  END IF;

--  Check to see if ShipmentNumber orderseq has been incremented past the passed number
  SELECT orderseq_number INTO _test
  FROM orderseq
  WHERE (orderseq_name='ShipmentNumber');

  IF ((_test - 1) <> pNumber) THEN
    RETURN FALSE;
  END IF;

--  Decrement the orderseq, releasing the passed number
  UPDATE orderseq
  SET orderseq_number = (orderseq_number - 1)
  WHERE (orderseq_name='ShipmentNumber');

  RETURN TRUE;

END;

Function: public.releasesohead(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;

BEGIN

  DELETE FROM soheadlock
   WHERE ( (soheadlock_sohead_id=pSoheadid)
     AND   (soheadlock_username=getEffectiveXtUser())
     AND   (soheadlock_procpid=pg_backend_pid()) );

  RETURN TRUE;
END;

Function: public.releasesonumber(integer)

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('SoNumber', $1);

Function: public.releasesonumber(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
	IF (COALESCE($1, '') = '' OR $1 ~ '[^0-9]')
	THEN
	--do nothing;
	RETURN 1;
	ELSE
	RETURN releaseNumber('SoNumber', $1::INTEGER);
	
	END IF;
END;

Function: public.releaseunusedbillingheader(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCobmiscid ALIAS FOR $1;
  _p RECORD;

BEGIN

  IF ( ( SELECT cobmisc_posted
         FROM cobmisc
         WHERE (cobmisc_id=pCobmiscid) ) ) THEN
    RETURN -1;
  END IF;

  SELECT cobill_id INTO _p
    FROM cobill
   WHERE (cobill_cobmisc_id=pCobmiscid)
   LIMIT 1;
  IF (FOUND) THEN
    RETURN -2;
  END IF;

  DELETE FROM cobmisc
  WHERE (cobmisc_id=pCobmiscid);

  RETURN 0;
END;

Function: public.releasevonumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('VcNumber', $1) > 0;

Function: public.releasewo(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  releaseChildren ALIAS FOR $2;
  returnCode INTEGER;
BEGIN
  UPDATE wo
  SET wo_status='R'
  WHERE ((wo_status='E')
   AND (wo_id=pWoid));

  IF (releaseChildren) THEN
    returnCode := (SELECT MAX(releaseWo(wo_id, TRUE))
                   FROM wo
                   WHERE ((wo_ordtype='W')
                    AND (wo_ordid=pWoid)));
  END IF;

  RETURN 0;
END;

Function: public.releasewonumber(integer)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT releaseNumber('WoNumber', $1) > 0;

Function: public.relocateinventory(integer, integer, integer, numeric, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN relocateInventory($1, $2, $3, $4, $5, CURRENT_TIMESTAMP);
END;

Function: public.relocateinventory(integer, integer, integer, numeric, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSourceItemlocid      ALIAS FOR $1;
  pTargetLocationid     ALIAS FOR $2;
  pItemsiteid           ALIAS FOR $3;
  pQty                  ALIAS FOR $4;
  pComments             ALIAS FOR $5;
  _GlDistTS             TIMESTAMP WITH TIME ZONE := $6;
  _targetItemlocid      INTEGER;
  _invhistid            INTEGER;
  _p RECORD;
  _qty NUMERIC;
  _itemlocSeries INTEGER := NEXTVAL('itemloc_series_seq');

BEGIN

    IF ((_GlDistTS IS NULL) OR (CAST(_GlDistTS AS date)=CURRENT_DATE)) THEN
      _GlDistTS := CURRENT_TIMESTAMP;
    END IF;

--  Make sure the passed itemsite points to a real item
  IF ( ( SELECT (item_type IN ('R', 'F') OR itemsite_costmethod = 'J')
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

--  Cache some parameters
  SELECT itemloc_ls_id,
         itemloc_itemsite_id AS itemsiteid,
         itemloc_expiration,
         itemloc_warrpurc,
         itemloc_qty,
         sourceloc.location_netable AS sourcenet,
         targetloc.location_netable AS targetnet INTO _p
  FROM itemloc, location AS sourceloc, location AS targetloc
  WHERE ( (itemloc_location_id=sourceloc.location_id)
   AND (targetloc.location_id=pTargetLocationid)
   AND (itemloc_id=pSourceItemlocid) );

--  Check to make sure the qty being transfered exists
  IF (_p.itemloc_qty < pQty) THEN
    RETURN -1;
  END IF;

--  Create the RL transaction
  SELECT NEXTVAL('invhist_invhist_id_seq') INTO _invhistid;
  INSERT INTO invhist
  ( invhist_id, invhist_itemsite_id,
    invhist_transtype, invhist_invqty,
    invhist_qoh_before, invhist_qoh_after,
    invhist_comments,   invhist_transdate,
    invhist_invuom, invhist_unitcost, invhist_costmethod,
    invhist_value_before, invhist_value_after, invhist_series) 
  SELECT _invhistid, itemsite_id,
         'RL', 0,
         itemsite_qtyonhand, itemsite_qtyonhand,
         pComments, _GlDistTS,
         uom_name,
         CASE WHEN (itemsite_costmethod='A') THEN avgcost(itemsite_id)
              ELSE stdCost(item_id)
         END, itemsite_costmethod,
         itemsite_value, itemsite_value, _itemlocSeries
  FROM item, itemsite, uom
  WHERE ((itemsite_item_id=item_id)
   AND (item_inv_uom_id=uom_id)
   AND (itemsite_controlmethod <> 'N')
   AND (itemsite_id=pItemsiteid));

--  Relocate the inventory from the source and record the transactions
  INSERT INTO invdetail
  ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
    invdetail_qty, invdetail_qty_before, invdetail_qty_after,
    invdetail_expiration, invdetail_warrpurc )
  SELECT _invhistid, itemloc_location_id, itemloc_ls_id,
         (pQty * -1), itemloc_qty, (itemloc_qty - pQty),
         itemloc_expiration, itemloc_warrpurc
  FROM itemloc
  WHERE (itemloc_id=pSourceItemlocid);

  UPDATE itemloc
  SET itemloc_qty=(itemloc_qty - pQty)
  FROM itemsite
  WHERE ( (itemloc_itemsite_id=itemsite_id)
   AND (NOT itemsite_freeze)
   AND (itemloc_id=pSourceItemlocid) );

--  Check to see if there is anything left at the source Itemloc and delete if not
  DELETE FROM itemloc
  WHERE ( (itemloc_qty=0)
   AND (itemloc_id=pSourceItemlocid) );

--  Check to see if any of the current Lot/Serial #/Expiration exists at the target location
  SELECT itemloc_id INTO _targetItemlocid
  FROM itemloc 
  WHERE ( (COALESCE(itemloc_ls_id, -1)=COALESCE(_p.itemloc_ls_id,-1))
   AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_p.itemloc_expiration,endOfTime()))
   AND (COALESCE(itemloc_warrpurc,endOfTime())=COALESCE(_p.itemloc_warrpurc,endOfTime()))
   AND (itemloc_itemsite_id=pItemsiteid)
   AND (itemloc_location_id=pTargetLocationid) );

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _targetItemlocid;
    INSERT INTO itemloc
    ( itemloc_id, itemloc_itemsite_id, itemloc_location_id,
      itemloc_ls_id, itemloc_expiration, itemloc_warrpurc, itemloc_qty )
    VALUES
    ( _targetItemlocid, pItemsiteid, pTargetLocationid,
      _p.itemloc_ls_id, _p.itemloc_expiration, _p.itemloc_warrpurc, 0 );
  END IF;

--  Relocate the inventory to the resultant target and record the transactions
  INSERT INTO invdetail
  ( invdetail_invhist_id, invdetail_location_id, invdetail_ls_id,
    invdetail_qty, invdetail_qty_before, invdetail_qty_after,
    invdetail_expiration, invdetail_warrpurc )
  SELECT _invhistid, pTargetLocationid, _p.itemloc_ls_id,
         pQty, itemloc_qty, (itemloc_qty + pQty), 
         _p.itemloc_expiration, _p.itemloc_warrpurc
  FROM itemloc
  WHERE (itemloc_id=_targetItemlocid);

  UPDATE itemloc
  SET itemloc_qty=(itemloc_qty + pQty)
  FROM itemsite
  WHERE ( (itemloc_itemsite_id=itemsite_id)
   AND (NOT itemsite_freeze)
   AND (itemloc_id=_targetItemlocid) );

  UPDATE invhist
  SET invhist_hasdetail=TRUE
  WHERE (invhist_id=_invhistid);

--  Post in incomming or outgoing NN transaction if required
  IF (_p.sourcenet <> _p.targetnet) THEN
    IF (_p.targetnet) THEN
      _qty = (pQty * -1);
    ELSE
      _qty = pQty;
    END IF;

    INSERT INTO invhist
    ( invhist_itemsite_id,
      invhist_transtype, invhist_invqty,
      invhist_qoh_before, invhist_qoh_after,
      invhist_docnumber, invhist_comments, invhist_transdate,
      invhist_invuom, invhist_unitcost, invhist_costmethod,
      invhist_value_before, invhist_value_after, invhist_series) 
    SELECT itemsite_id,
           'NN', (_qty * -1),
           itemsite_qtyonhand, (itemsite_qtyonhand - _qty),
           '', '', _GlDistTS,
           uom_name,
           CASE WHEN (itemsite_costmethod='A') THEN avgcost(itemsite_id)
                ELSE stdCost(item_id)
           END, itemsite_costmethod,
           itemsite_value, itemsite_value, _itemlocSeries
    FROM item, itemsite, uom
    WHERE ( (itemsite_item_id=item_id)
     ANd (item_inv_uom_id=uom_id)
     AND (itemsite_controlmethod <> 'N')
     AND (itemsite_id=_p.itemsiteid) );

    UPDATE itemsite
    SET itemsite_qtyonhand = (itemsite_qtyonhand - _qty),
        itemsite_nnqoh = (itemsite_nnqoh + _qty)
    WHERE (itemsite_id=_p.itemsiteid);
  END IF;

--  Check to see if there is anything left at the target Itemloc and delete if not
--  Could be zero if relocate increased a negative quantity to zero
  DELETE FROM itemloc
  WHERE ( (itemloc_qty=0)
   AND (itemloc_id=_targetItemlocid) );

--  Return the invhist_id
  RETURN _invhistid;

END;

Function: public.reorderdate(integer, integer, boolean)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pLookAhead ALIAS FOR $2;
  pIncludePlanned ALIAS FOR $3;
  _runningAvailability NUMERIC;
  _reorderLevel NUMERIC;
  _availability RECORD;

BEGIN

--  Make sure that we know how to handle the passed part
  IF ( SELECT (NOT (item_type IN ('M', 'P')))
       FROM item, itemsite
       WHERE ( (itemsite_item_id=item_id)
        AND (itemsite_id=pItemsiteid) ) ) THEN
    RETURN NULL;
  END IF;

--  Load the initial QOH
  SELECT itemsite_qtyonhand INTO _runningAvailability
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

--  Grab the Reorder Level, if any
  IF ( ( SELECT itemsite_useparams
         FROM itemsite
         WHERE (itemsite_id=pItemsiteid) ) ) THEN
    SELECT itemsite_reorderlevel INTO _reorderLevel
    FROM itemsite
    WHERE (itemsite_id=pItemsiteid);
  ELSE
    _reorderLevel := 0;
  END IF;

--  If we are already below the Reorder Level then we should order ASAP
  IF (_runningAvailability <= _reorderLevel) THEN
    RETURN CURRENT_DATE;
  END IF;

--  Grab all of the availability trigger points
  FOR _availability IN SELECT 1 AS seq,
                              wo_duedate AS orderdate,
                              (noNeg(wo_qtyord - wo_qtyrcv)) AS balance
                       FROM wo
                       WHERE ((wo_status IN ('O', 'E', 'R', 'I'))
                        AND (wo_duedate <= (CURRENT_DATE + pLookAhead))
                        AND (wo_itemsite_id=pItemsiteid))

                      UNION SELECT 2 AS seq,
                                   womatl_duedate AS orderdate,
                                   (noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss)) * -1) AS balance
                      FROM womatl, wo, itemsite
                      WHERE ((wo_status IN ('O', 'E', 'R', 'I'))
                       AND (womatl_wo_id=wo_id)
                       AND (womatl_itemsite_id=itemsite_id)
                       AND (womatl_duedate <= (CURRENT_DATE + pLookahead))
                       AND (womatl_itemsite_id=pItemsiteid))

                      UNION SELECT 1 AS seq,
                                   poitem_duedate AS orderdate,
                                   (noNeg(poitem_qty_ordered - poitem_qty_received) * poitem_invvenduomratio) AS balance
                      FROM pohead, poitem
                      WHERE ((poitem_pohead_id=pohead_id)
                       AND (poitem_status = 'O')
                       AND (poitem_duedate <= (CURRENT_DATE + pLookAhead))
                       AND (poitem_itemsite_id=pItemsiteid))

                      UNION SELECT 2 AS seq,
                                   coitem_scheddate AS orderdate,
                                   (noNeg(coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) * -1) AS balance
                      FROM coitem, cohead
                      WHERE ((coitem_status = 'O')
                       AND (coitem_cohead_id=cohead_id)
                       AND (coitem_scheddate <= (CURRENT_DATE + pLookAhead))
                       AND (coitem_itemsite_id=pItemsiteid))

                      UNION SELECT 2 AS seq,
                                   planord_startdate AS orderdate,
                                   (planreq_qty * -1) AS balance
                      FROM planreq, planord
                      WHERE ( (pIncludePlanned)
                       AND (planreq_source='P')
                       AND (planreq_source_id=planord_id)
                       AND (planord_startdate <= (CURRENT_DATE + pLookAhead))
                       AND (planord_itemsite_id=pItemsiteid) )

                      UNION SELECT 1 AS seq,
                                   planord_duedate AS orderdate,
                                   planord_qty AS balance
                      FROM planord
                      WHERE ( (pIncludePlanned)
                       AND (planord_duedate <= (CURRENT_DATE + pLookAhead))
                       AND (planord_itemsite_id=pItemsiteid) )

                      ORDER BY orderdate, seq LOOP

--  Calculate the new projected availability
    _runningAvailability := (_runningAvailability + _availability.balance);

--  Check to see if the project availability drop below the reorder level
    IF (_runningAvailability < _reorderLevel) THEN
      RETURN _availability.orderdate;
    END IF;

  END LOOP;

--  The reorder level was not reached within the look ahead period
  RETURN NULL;

END;

Function: public.replaceallvoidedapchecks(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'replaceAllVoidedAPChecks() is deprecated - use replaceAllVoidedChecks() instead';
  RETURN replaceAllVoidedChecks($1);
END;

Function: public.replaceallvoidedchecks(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid	ALIAS FOR $1;
  _returnValue	INTEGER := 0;

BEGIN

  SELECT MIN(replaceVoidedCheck(checkhead_id)) INTO _returnValue
    FROM checkhead
    WHERE ( (checkhead_void)
     AND (NOT checkhead_posted)
     AND (NOT checkhead_replaced)
     AND (NOT checkhead_deleted)
     AND (checkhead_bankaccnt_id=pBankaccntid) );

  RETURN _returnValue;

END;

Function: public.replacevoidedapcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'replaceVoidedAPCheck() is deprecated - use replaceVoidedCheck()';
  RETURN replaceVoidedCheck($1);
END;

Function: public.replacevoidedcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid	ALIAS FOR $1;
  _newCheckid	INTEGER;

BEGIN
  IF ( ( SELECT ( (NOT checkhead_void) OR checkhead_posted OR checkhead_replaced )
         FROM checkhead
         WHERE (checkhead_id=pCheckid) ) ) THEN
    RETURN -1;
  END IF;

  -- has someone created a new check for one of the items while this was void?
  IF EXISTS (SELECT dup.checkitem_id
             FROM checkitem orig, checkitem dup, checkhead AS duphead
             WHERE ((COALESCE(orig.checkitem_aropen_id,-1)=COALESCE(dup.checkitem_aropen_id,-1))
                AND (COALESCE(orig.checkitem_apopen_id,-1)=COALESCE(dup.checkitem_apopen_id,-1))
                AND (orig.checkitem_checkhead_id!=dup.checkitem_checkhead_id)
                AND (dup.checkitem_checkhead_id=duphead.checkhead_id)
                AND (NOT duphead.checkhead_void)
                AND (orig.checkitem_checkhead_id=pCheckid))) THEN
    RETURN -2;
  END IF;

  SELECT NEXTVAL('checkhead_checkhead_id_seq') INTO _newCheckid;

  INSERT INTO checkhead
  ( checkhead_id, checkhead_recip_id, checkhead_recip_type,
    checkhead_bankaccnt_id, checkhead_checkdate,
    checkhead_number, checkhead_amount,
    checkhead_for, checkhead_journalnumber,
    checkhead_notes,
    checkhead_misc, checkhead_expcat_id, checkhead_curr_id )
  SELECT _newCheckid, checkhead_recip_id, checkhead_recip_type,
	 checkhead_bankaccnt_id, checkhead_checkdate,
	 -1, -- fetchNextCheckNumber(checkhead_bankaccnt_id),
         checkhead_amount,
	 checkhead_for, checkhead_journalnumber,
         checkhead_notes || '
Replaces voided check ' || checkhead_number,
	 checkhead_misc, checkhead_expcat_id, checkhead_curr_id
  FROM checkhead
  WHERE (checkhead_id=pCheckid);

  INSERT INTO checkitem
  ( checkitem_checkhead_id, checkitem_amount, checkitem_discount,
    checkitem_ponumber, checkitem_vouchernumber, checkitem_invcnumber,
    checkitem_apopen_id, checkitem_aropen_id,
    checkitem_docdate, checkitem_curr_id, checkitem_curr_rate )
  SELECT _newCheckid, checkitem_amount, checkitem_discount,
         checkitem_ponumber, checkitem_vouchernumber, checkitem_invcnumber,
	 checkitem_apopen_id, checkitem_aropen_id,
	 checkitem_docdate, checkitem_curr_id, checkitem_curr_rate
  FROM checkitem
  WHERE (checkitem_checkhead_id=pCheckid);

  UPDATE checkhead
  SET checkhead_replaced=TRUE
  WHERE (checkhead_id=pCheckid);

  RETURN _newCheckid;

END;

Function: public.reprioritizewo(integer, integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  pPriority ALIAS FOR $2;
  pChangeChildren ALIAS FOR $3;
  _status CHAR(1);
  _result INTEGER;

BEGIN

  SELECT wo_status INTO _status
  FROM wo
  WHERE (wo_id=pWoid);

  IF (NOT (_status IN ('O', 'E','R','I'))) THEN
    return -1;
  END IF;

  UPDATE wo
  SET wo_priority=pPriority
  WHERE (wo_id=pWoid);

  IF ( (_status IN ('E','R','I')) AND (pChangeChildren) ) THEN
    SELECT COALESCE(MIN(reprioritizeWo(wo_id, pPriority, TRUE)), 1) INTO _result
    FROM wo
    WHERE ( (wo_ordtype='W')
     AND (wo_ordid=pWoid) );
  ELSE
    _result = 1;
  END IF;

  RETURN _result;

END;

Function: public.resetdbobjperms()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _count        INTEGER := 0;
BEGIN
  SELECT SUM(resetDBObjPerms(nspname || '.' || relname)) INTO _count
  FROM pg_catalog.pg_class, pg_catalog.pg_namespace
  WHERE (relkind IN ('r', 'S', 'v')
    AND  (relnamespace=pg_namespace.oid)
    AND  (nspname IN ('public', 'api')));

  RETURN _count;
END;

Function: public.resetdbobjperms(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pObjname      ALIAS FOR $1;
BEGIN
  EXECUTE 'ALTER TABLE '   || pObjname || ' OWNER TO ' || getEffectiveXtUser() || ';';
  EXECUTE 'REVOKE ALL ON ' || pObjname || ' FROM PUBLIC;';
  EXECUTE 'GRANT  ALL ON ' || pObjname || ' TO GROUP xtrole;';
  RETURN 1;
END;

Function: public.resetlowlevelcode(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

    pItemId ALIAS FOR $1;
    _result	INTEGER;
    _counterNum	INTEGER	:= 1;
    _feedBackNum INTEGER := 1;
    _r                  RECORD;

BEGIN
    DELETE FROM costUpdate;

    IF pItemId = -1 THEN 	-- -1 is an invalid item_id => do them all
	INSERT INTO costUpdate ( costUpdate_item_id, costUpdate_item_type )
			SELECT item_id, item_type
			FROM   item;

        -- Recalculate the Item Lowlevel codes
        WHILE _feedBackNum > 0 LOOP
            SELECT updateLowlevel(_counterNum) INTO _feedBackNum;
            _counterNum := _counterNum + 1;
        END LOOP;

    ELSE
	INSERT INTO costUpdate ( costUpdate_item_id, costUpdate_item_type )
			SELECT item_id, item_type
			FROM   item
                        WHERE (item_id=pItemId);
      FOR _r IN SELECT item_id, bomdata_bomwork_level, item_type
                FROM item,
                     indentedBOM(pItemId, getActiveRevId('BOM',pItemId),0,0)
                WHERE (bomdata_item_id=item_id)
                ORDER BY bomdata_bomwork_level LOOP

        -- this only works because of the ORDER BY in the loop SELECT
        UPDATE costUpdate
        SET costupdate_lowlevel_code = _r.bomdata_bomwork_level
        WHERE (costupdate_item_id=_r.item_id);

        IF (NOT FOUND) THEN
          INSERT INTO costUpdate (
            costUpdate_item_id, costUpdate_lowlevel_code, costUpdate_item_type
          ) VALUES (
            _r.item_id, _r.bomdata_bomwork_level, _r.item_type
          );
        END IF;
      END LOOP;

    END IF;

    SELECT count(*) INTO _result
    FROM costUpdate;

    RETURN _result;

END;

Function: public.resetqohbalance(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN resetQOHBalance($1, CURRENT_TIMESTAMP);
END;

Function: public.resetqohbalance(integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid   ALIAS FOR $1;
  pGlDistTS     ALIAS FOR $2;
  _invhistid    INTEGER;
  _itemlocSeries INTEGER;

BEGIN

  IF ( ( SELECT ( (itemsite_controlmethod IN ('L', 'S')) OR
                  (item_type = 'R') OR
                  (itemsite_costmethod = 'J') OR
                  (itemsite_loccntrl) OR
                  (itemsite_qtyonhand > 0) )
         FROM itemsite, item
         WHERE ( (itemsite_item_id=item_id)
          AND (itemsite_id=pItemsiteid) ) ) ) THEN
    RETURN 0;
  END IF;

  _itemlocSeries := NEXTVAL('itemloc_series_seq');

  SELECT postInvTrans( itemsite_id, 'AD', (itemsite_qtyonhand * -1),
                       'I/M', '', '', 'RESET',
                       'Reset QOH Balance to 0',
                       costcat_asset_accnt_id, costcat_adjustment_accnt_id,
                       _itemlocSeries, pGlDistTS ) INTO _invhistid
  FROM itemsite, costcat
  WHERE ( (itemsite_costcat_id=costcat_id)
   AND (itemsite_id=pItemsiteid) );

  PERFORM postItemLocSeries(_itemlocSeries);

  RETURN _invhistid;

END;

Function: public.resolvecosaccount(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, pCustid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_cos_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvecosaccount(pshipzoneid integer, psaletypeid integer, pcustid integer, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, 'IS', pCustid, pSaletypeid, pShipzoneid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_cos_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvecowaccount(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, pCustid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_cow_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvecowaccount(pshipzoneid integer, psaletypeid integer, pcustid integer, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, 'IS', pCustid, pSaletypeid, pShipzoneid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_cow_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvecreditaccount(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, pCustid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_credit_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvecreditaccount(pshipzoneid integer, psaletypeid integer, pcustid integer, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, 'IS', pCustid, pSaletypeid, pShipzoneid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_credit_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvesalesaccount(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, pCustid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_sales_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.resolvesalesaccount(pshipzoneid integer, psaletypeid integer, pcustid integer, pitemsiteid integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _salesaccntid INTEGER;
  _accntid INTEGER;

BEGIN

  SELECT findSalesAccnt(pItemsiteid, 'IS', pCustid, pSaletypeid, pShipzoneid) INTO _salesaccntid;
  IF (_salesaccntid = -1) THEN
    SELECT getUnassignedAccntId() INTO _accntid;
  ELSE
    SELECT salesaccnt_sales_accnt_id INTO _accntid
    FROM salesaccnt
    WHERE (salesaccnt_id=_salesaccntid);
  END IF;

  RETURN _accntid;

END;

Function: public.restoresaleshistory(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAsohistid ALIAS FOR $1;

BEGIN

  INSERT INTO cohist ( cohist_id,
                       cohist_cust_id,
                       cohist_itemsite_id,
                       cohist_shipdate,
                       cohist_invcdate,
                       cohist_duedate,
                       cohist_promisedate,
                       cohist_ordernumber,
                       cohist_invcnumber,
                       cohist_qtyshipped,
                       cohist_unitprice,
                       cohist_unitcost,
                       cohist_billtoname,
                       cohist_billtoaddress1,
                       cohist_billtoaddress2,
                       cohist_billtoaddress3,
                       cohist_billtocity,
                       cohist_billtostate,
                       cohist_billtozip,
                       cohist_shiptoname,
                       cohist_shiptoaddress1,
                       cohist_shiptoaddress2,
                       cohist_shiptoaddress3,
                       cohist_shiptocity,
                       cohist_shiptostate,
                       cohist_shiptozip,
                       cohist_shipto_id,
                       cohist_shipvia,
                       cohist_salesrep_id,
                       cohist_misc_type,
                       cohist_misc_descrip,
                       cohist_misc_id,
                       cohist_commission,
                       cohist_commissionpaid,
                       cohist_doctype,
                       cohist_orderdate,
                       cohist_imported,
                       cohist_ponumber,
                       cohist_curr_id,
                       cohist_taxtype_id,
                       cohist_taxzone_id )
  SELECT asohist_id,
         CASE asohist_cust_id WHEN -1 THEN NULL ELSE asohist_cust_id END,
         asohist_itemsite_id,
         asohist_shipdate,
         asohist_invcdate,
         asohist_duedate,
         asohist_promisedate,
         asohist_ordernumber,
         asohist_invcnumber,
         asohist_qtyshipped,
         asohist_unitprice,
         asohist_unitcost,
         asohist_billtoname,
         asohist_billtoaddress1,
         asohist_billtoaddress2,
         asohist_billtoaddress3,
         asohist_billtocity,
         asohist_billtostate,
         asohist_billtozip,
         asohist_shiptoname,
         asohist_shiptoaddress1,
         asohist_shiptoaddress2,
         asohist_shiptoaddress3,
         asohist_shiptocity,
         asohist_shiptostate,
         asohist_shiptozip,
         asohist_shipto_id,
         asohist_shipvia,
         CASE asohist_salesrep_id WHEN -1 THEN NULL ELSE asohist_salesrep_id END,
         asohist_misc_type,
         asohist_misc_descrip,
         asohist_misc_id,
         asohist_commission,
         asohist_commissionpaid,
         asohist_doctype,
         asohist_orderdate,
         asohist_imported,
         asohist_ponumber,
	 asohist_curr_id,
         asohist_taxtype_id,
         asohist_taxzone_id
  FROM asohist
  WHERE (asohist_id=pAsohistid);

  INSERT INTO cohisttax ( taxhist_id,
                          taxhist_parent_id,
                          taxhist_taxtype_id,
                          taxhist_tax_id,
                          taxhist_basis,
                          taxhist_basis_tax_id,
                          taxhist_sequence,
                          taxhist_percent,
                          taxhist_amount,
                          taxhist_tax,
                          taxhist_docdate,
                          taxhist_distdate,
                          taxhist_curr_id,
                          taxhist_curr_rate,
                          taxhist_journalnumber )
  SELECT taxhist_id,
         taxhist_parent_id,
         taxhist_taxtype_id,
         taxhist_tax_id,
         taxhist_basis,
         taxhist_basis_tax_id,
         taxhist_sequence,
         taxhist_percent,
         taxhist_amount,
         taxhist_tax,
         taxhist_docdate,
         taxhist_distdate,
         taxhist_curr_id,
         taxhist_curr_rate,
         taxhist_journalnumber
  FROM asohisttax
  WHERE (taxhist_parent_id=pAsohistid);

  DELETE FROM asohisttax
  WHERE (taxhist_parent_id=pAsohistid);

  DELETE FROM asohist
  WHERE (asohist_id=pAsohistid);

  RETURN pAsohistid;

END;

Function: public.returncompleteshipment(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN returnCompleteShipment($1, 0, CURRENT_TIMESTAMP);
END;

Function: public.returncompleteshipment(integer, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pshipheadid		ALIAS FOR $1;
  _itemlocSeries	INTEGER := $2;
  _timestamp		TIMESTAMP WITH TIME ZONE := $3;
  _r RECORD;
  _result 		RECORD;
  _shiphead_number	TEXT := '';
  _count		INTEGER := 0;
  _countsum		INTEGER := 0;

BEGIN
  FOR _r IN SELECT shipitem_id
            FROM shipitem, shiphead
            WHERE ( (shipitem_shiphead_id=shiphead_id)
             AND (NOT shiphead_shipped)
             AND (shiphead_id=pshipheadid) ) LOOP
    _itemlocSeries := returnShipmentTransaction(_r.shipitem_id, _itemlocSeries, _timestamp);
  END LOOP;

  FOR _result IN SELECT shiphead_number
                   FROM shiphead
                  WHERE ( (shiphead_id=pshipheadid) ) LOOP
    _shiphead_number := _result.shiphead_number;
  END LOOP;

  SELECT COUNT(*) INTO _count
    FROM shipdata
   WHERE(shipdata_shiphead_number=_shiphead_number);

  SELECT COUNT(*) INTO _countsum
    FROM shipdatasum
   WHERE(shipdatasum_shiphead_number=_shiphead_number);

  IF (_count > 0) THEN
    DELETE FROM shipdata
     WHERE(shipdata_shiphead_number=_shiphead_number);
  END IF;
  IF (_countsum > 0) THEN
    DELETE FROM shipdatasum
     WHERE(shipdatasum_shiphead_number=_shiphead_number);
  END IF;

  DELETE FROM pack
   WHERE(pack_shiphead_id=pshipheadid);
  DELETE FROM shiphead
  WHERE (shiphead_id=pshipheadid);

  RETURN _itemlocSeries;

END;

Function: public.returnitemshipments(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN returnItemShipments('SO', $1, 0, CURRENT_TIMESTAMP);
END;

Function: public.returnitemshipments(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN returnItemShipments('SO', $1, $2, CURRENT_TIMESTAMP);
END;

Function: public.returnitemshipments(text, integer, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  pitemid		ALIAS FOR $2;
  _itemlocSeries	INTEGER				:= $3;
  _timestamp		TIMESTAMP WITH TIME ZONE	:= $4;
  _invhistid INTEGER;
  _r RECORD;

BEGIN

  IF (COALESCE(_itemlocSeries,0) = 0 ) THEN
    _itemlocSeries := NEXTVAL('itemloc_series_seq');
  END IF;

  FOR _r IN 
    SELECT shipitem_id
    FROM shipitem
      JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
    WHERE ((NOT shiphead_shipped)
      AND  (shiphead_order_type=pordertype)
      AND  (shipitem_orderitem_id=pitemid))
  LOOP

    SELECT returnShipmentTransaction(_r.shipitem_id, _itemlocSeries, _timestamp) INTO _itemlocSeries;

    IF (_itemlocSeries < 0) THEN
      RETURN _itemlocSeries;
    END IF;

  END LOOP;

  RETURN _itemlocSeries;

END;

Function: public.returnshipmenttransaction(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN returnShipmentTransaction($1, 0, CURRENT_TIMESTAMP);
END;

Function: public.returnshipmenttransaction(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN returnShipmentTransaction($1, $2, CURRENT_TIMESTAMP);
END;

Function: public.returnshipmenttransaction(integer, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipitemId           ALIAS FOR $1;
  pItemlocSeries        ALIAS FOR $2;
  pTimestamp            ALIAS FOR $3;
  _itemlocSeries        INTEGER;
  _invhistid            INTEGER;
  _itemlocrsrvid        INTEGER;
  _coheadid             INTEGER;
  _rows                 INTEGER;
  _r                    RECORD;
  _rsrv                 RECORD;

BEGIN

    IF (COALESCE(pItemlocSeries, 0) = 0 ) THEN
      _itemlocSeries := NEXTVAL('itemloc_series_seq');
    ELSE
      _itemlocSeries := pItemlocSeries;
    END IF;
  
    -- Find the shipment transaction record
    SELECT shipitem.*,
           shiphead_id, shiphead_number, shiphead_order_type, invhist_series,
           itemsite_loccntrl, itemsite_costmethod, itemsite_controlmethod,
           cohead_prj_id AS prj_id     
      INTO _r
    FROM shipitem
      JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
      JOIN invhist ON (invhist_id=shipitem_invhist_id)
      JOIN itemsite ON (itemsite_id=invhist_itemsite_id)
      LEFT OUTER JOIN cohead ON ((shiphead_order_type = 'SO') AND (shiphead_order_id = cohead_id))
    WHERE ((NOT shiphead_shipped)
      AND  (shipitem_id=pShipitemId));
      
    GET DIAGNOSTICS _rows = ROW_COUNT;
    IF (_rows = 0 ) THEN
      -- Was it a non-controlled sales order item?
      SELECT shipitem.*,
             shiphead_id, shiphead_number, shiphead_order_type,
             itemsite_loccntrl, itemsite_costmethod, itemsite_controlmethod,
             cohead_prj_id AS prj_id
      INTO _r
      FROM shipitem
        JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
        JOIN coitem ON (shipitem_orderitem_id=coitem_id)
        JOIN cohead ON (cohead_id=coitem_cohead_id)
        JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
      WHERE ((NOT shiphead_shipped)
        AND  (shipitem_id=pShipitemId)
        AND  (shiphead_order_type = 'SO'));
    END IF;
    
    GET DIAGNOSTICS _rows = ROW_COUNT;
    IF (_rows = 0 AND fetchmetricbool('MultiWhs') ) THEN
      -- Was it a non-controlled transfer order item?
      SELECT shipitem.*,
             shiphead_id, shiphead_number, shiphead_order_type,
             itemsite_loccntrl, itemsite_costmethod, itemsite_controlmethod,
             NULL AS prj_id
      INTO _r
      FROM shipitem
        JOIN shiphead ON (shiphead_id=shipitem_shiphead_id)
        JOIN toitem ON (shipitem_orderitem_id=toitem_id)
        JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
      WHERE ((NOT shiphead_shipped)
        AND  (shipitem_id=pShipitemId)
        AND  (shiphead_order_type = 'TO'));
    END IF;
    
    IF (_rows > 0 ) THEN  
      IF (_r.shiphead_order_type = 'SO') THEN
        -- Handle inventory transaction
        IF (_r.itemsite_controlmethod != 'N' OR _r.itemsite_costmethod = 'J') THEN
          SELECT postInvTrans( itemsite_id, 'RS', (_r.shipitem_qty * coitem_qty_invuomratio),
                               'S/R', _r.shiphead_order_type, formatSoNumber(_r.shipitem_orderitem_id),
                               shiphead_number, 'Return from Shipping',
                               costcat_asset_accnt_id, getPrjAccntId(_r.prj_id, costcat_shipasset_accnt_id),
                               _itemlocSeries, pTimestamp, _r.shipitem_value, _r.shipitem_invhist_id ) INTO _invhistid
          FROM coitem, itemsite, costcat, shiphead, shipitem
          WHERE ((coitem_itemsite_id=itemsite_id)
            AND  (itemsite_costcat_id=costcat_id)
            AND  (coitem_id=_r.shipitem_orderitem_id)
            AND  (shiphead_order_type=_r.shiphead_order_type)
            AND  (shiphead_id=shipitem_shiphead_id)
            AND  (shipitem_orderitem_id=_r.shipitem_orderitem_id));
 
          -- We know the distribution so post this through so the any w/o activity knows about it
          PERFORM postItemlocseries(_itemlocSeries);
        END IF;
 
        IF (_r.itemsite_costmethod = 'J') THEN   
          -- Reopen the work order
          UPDATE wo SET wo_status = 'I' WHERE ((wo_ordtype='S') AND (wo_ordid=_r.shipitem_orderitem_id));
          
          --  Job cost, so correct Production Posting referencing original receipt for reverse info.
          PERFORM correctProduction(wo_id, invhist_invqty, false, _itemlocSeries, pTimestamp, invhist_id)
          FROM wo, invhist
          WHERE ((wo_ordtype = 'S')
            AND  (wo_ordid = _r.shipitem_orderitem_id) 
            AND  (invhist_series=_r.invhist_series)
            AND  (invhist_transtype='RM'));
             
          --  Return eligble material
          PERFORM returnWoMaterial(womatlpost_womatl_id, _itemlocSeries, pTimestamp, womatlpost_invhist_id)
          FROM womatlpost, invhist m, invhist s 
          WHERE ((womatlpost_invhist_id=m.invhist_id)
            AND  (m.invhist_series=s.invhist_series)
            AND  (m.invhist_transtype='IM')
            AND  (s.invhist_id=_r.shipitem_invhist_id));

        END IF; -- end Job Costing

      ELSIF (_r.shiphead_order_type = 'TO') THEN
        SELECT postInvTrans(itemsite_id, 'RS', _r.shipitem_qty,
                            'S/R', _r.shiphead_order_type, formatToNumber(toitem_id),
                            tohead_number, 'Return from Shipping',
                            costcat_asset_accnt_id, costcat_shipasset_accnt_id,
                            _itemlocSeries, pTimestamp, _r.shipitem_value, _r.shipitem_invhist_id ) INTO _invhistid
        FROM toitem, tohead, itemsite, costcat
        WHERE ((toitem_item_id=itemsite_item_id)
          AND  (toitem_tohead_id=tohead_id)
  	  AND  (tohead_src_warehous_id=itemsite_warehous_id)
          AND  (itemsite_costcat_id=costcat_id)
          AND  (toitem_id=_r.shipitem_orderitem_id));

      ELSE
        -- Don't know what kind of order this is
        RETURN -11;
      END IF;

      UPDATE shiphead
      SET shiphead_sfstatus='D'
      WHERE ((shiphead_id=_r.shiphead_id)
        AND  (shiphead_sfstatus='P'));

       -- Handle reservation if applicable
      IF (fetchmetricbool('EnableSOReservations')) THEN
        UPDATE coitem
          SET coitem_qtyreserved = (coitem_qtyreserved + shipitemrsrv_qty)
        FROM shipitemrsrv
        WHERE ((coitem_id=_r.shipitem_orderitem_id)
          AND  (shipitemrsrv_shipitem_id=_r.shipitem_id));

        -- Handle location reservations if applicable
        FOR _rsrv IN
          SELECT *
          FROM shipitemlocrsrv
          WHERE (shipitemlocrsrv_shipitem_id=_r.shipitem_id)
        LOOP
          -- See if a reservation record still exists
          SELECT itemlocrsrv_id, itemlocrsrv_qty INTO _itemlocrsrvid
          FROM itemlocrsrv JOIN itemloc ON (itemlocrsrv_itemloc_id=itemloc_id)
          WHERE ((itemlocrsrv_source = 'SO')
            AND  (itemlocrsrv_source_id = _r.shipitem_orderitem_id )
            AND  (itemloc_itemsite_id=_rsrv.shipitemlocrsrv_itemsite_id)
            AND  (itemloc_location_id=_rsrv.shipitemlocrsrv_location_id)
            AND  (COALESCE(itemloc_ls_id, -1)=COALESCE(_rsrv.shipitemlocrsrv_ls_id, -1))
            AND  (COALESCE(itemloc_expiration, endOfTime())=COALESCE(_rsrv.shipitemlocrsrv_expiration, endOfTime()))
            AND  (COALESCE(itemloc_warrpurc, endoftime())=COALESCE(_rsrv.shipitemlocrsrv_warrpurc, endoftime())) );

          GET DIAGNOSTICS _rows = ROW_COUNT;
          IF (_rows > 0 ) THEN  
            -- Update existing
            UPDATE itemlocrsrv
            SET itemlocrsrv_qty = (itemlocrsrv_qty + _rsrv.shipitemlocrsrv_qty)
            WHERE (itemlocrsrv_id=_itemlocrsvrid);
          ELSE
            -- Recreate record
            INSERT INTO itemlocrsrv
            SELECT nextval('itemlocrsrv_itemlocrsrv_id_seq'), 'SO', _r.shipitem_orderitem_id,
                   itemloc_id, _rsrv.shipitemlocrsrv_qty
            FROM itemloc
            WHERE ((itemloc_itemsite_id=_rsrv.shipitemlocrsrv_itemsite_id)
              AND  (itemloc_location_id=_rsrv.shipitemlocrsrv_location_id)
              AND  (COALESCE(itemloc_ls_id, -1)=COALESCE(_rsrv.shipitemlocrsrv_ls_id, -1))
              AND  (COALESCE(itemloc_expiration, endOfTime())=COALESCE(_rsrv.shipitemlocrsrv_expiration, endOfTime()))
              AND  (COALESCE(itemloc_warrpurc, endoftime())=COALESCE(_rsrv.shipitemlocrsrv_warrpurc, endoftime())) );
          END IF;
        END LOOP;
      END IF;
      
      DELETE FROM shipitem WHERE (shipitem_id = _r.shipitem_id );

      -- Clean up if this is the last shipitem on the shipment
      IF (NOT EXISTS(SELECT shipitem_shiphead_id
                     FROM shipitem
                     WHERE (shipitem_shiphead_id=_r.shiphead_id))) THEN
        DELETE FROM shipdata
         WHERE(shipdata_shiphead_number=_r.shiphead_number);
        DELETE FROM shipdatasum
         WHERE(shipdatasum_shiphead_number=_r.shiphead_number);
        DELETE FROM pack
         WHERE(pack_shiphead_id=_r.shiphead_id);
        DELETE FROM shiphead
         WHERE (shiphead_id=_r.shiphead_id);
      END IF;

    END IF;

    RETURN _itemlocSeries;

END;

Function: public.returnwomaterial(integer, integer, timestamp with time zone, integer)

Returns: integer

Language: PLPGSQL

Returns material by reversing a specific historical transaction

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pItemlocSeries ALIAS FOR $2;
  pGlDistTS ALIAS FOR $3;
  pInvhistId ALIAS FOR $4;
  _woNumber TEXT;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;
  _invqty NUMERIC;
  _womatlqty NUMERIC;
  _cost NUMERIC := 0;
  _rows INTEGER;

BEGIN

  _itemlocSeries := 0;

  SELECT invhist_invqty, invhist_invqty * invhist_unitcost INTO _invqty, _cost
  FROM invhist
  WHERE (invhist_id=pInvhistId);

  GET DIAGNOSTICS _rows = ROW_COUNT;
  
  IF (_rows = 0) THEN
    RAISE EXCEPTION 'No transaction found for invhist_id %', pInvhistId;
  END IF;
  
  SELECT itemuomtouom(itemsite_item_id, NULL, womatl_uom_id, _invqty)
    INTO _womatlqty
    FROM womatl, itemsite
    WHERE((womatl_itemsite_id=itemsite_id)
     AND (womatl_id=pWomatlid));

  GET DIAGNOSTICS _rows = ROW_COUNT;
  
  IF (_rows = 0) THEN
    _womatlqty := _invqty;
  END IF;

  IF ( SELECT (
         CASE WHEN (womatl_qtyreq >= 0) THEN
           womatl_qtyiss < _womatlqty
         ELSE
           womatl_qtyiss > _womatlqty
         END )
       FROM womatl
       WHERE ( womatl_id=pWomatlid ) ) THEN
    RETURN pItemlocSeries;
  END IF;

  SELECT formatWoNumber(womatl_wo_id) INTO _woNumber
  FROM womatl
  WHERE (womatl_id=pWomatlid);

  IF (pItemlocSeries = 0) THEN
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  ELSE
    _itemlocSeries = pItemlocSeries;
  END IF;

  -- Post the transaction
  SELECT postInvTrans( ci.itemsite_id, 'IM', (_invqty * -1), 
                       'W/O', 'WO', _woNumber, '',
                       ('Return ' || item_number || ' from Work Order'),
                       getPrjAccntId(wo_prj_id, pc.costcat_wip_accnt_id), cc.costcat_asset_accnt_id, _itemlocSeries, pGlDistTS,
                       -- Cost will be ignored by Standard Cost items sites
                       _cost, pInvhistId) INTO _invhistid
    FROM womatl, wo,
         itemsite AS ci, costcat AS cc,
         itemsite AS pi, costcat AS pc,
         item
   WHERE((womatl_itemsite_id=ci.itemsite_id)
     AND (ci.itemsite_costcat_id=cc.costcat_id)
     AND (womatl_wo_id=wo_id)
     AND (wo_itemsite_id=pi.itemsite_id)
     AND (pi.itemsite_costcat_id=pc.costcat_id)
     AND (ci.itemsite_item_id=item_id)
     AND (womatl_id=pWomatlid) );

--  Create linkage to the transaction created
  INSERT INTO womatlpost (womatlpost_womatl_id,womatlpost_invhist_id)
              VALUES (pWomatlid,_invhistid);

--  Decrease the parent W/O's WIP value by the value of the returned components
  UPDATE wo
  SET wo_wipvalue = (wo_wipvalue - (CASE WHEN(itemsite_costmethod IN ('A','J'))
                                              THEN _cost
                                         WHEN(itemsite_costmethod='S')
                                              THEN stdcost(itemsite_item_id) * _invqty
                                         ELSE 0.0 END )),
      wo_postedvalue = (wo_postedvalue - (CASE WHEN(itemsite_costmethod IN ('A','J'))
                                                    THEN _cost
                                               WHEN(itemsite_costmethod='S')
                                                    THEN stdcost(itemsite_item_id) * _invqty
                                               ELSE 0.0 END ))
  FROM womatl, itemsite
  WHERE ( (wo_id=womatl_wo_id)
   AND (womatl_itemsite_id=itemsite_id)
   AND (womatl_id=pWomatlid) );

  UPDATE womatl
  SET womatl_qtyiss = (womatl_qtyiss - _womatlqty),
      womatl_lastreturn = CURRENT_DATE
  WHERE (womatl_id=pWomatlid);

  RETURN _itemlocSeries;
END;

Function: public.returnwomaterial(integer, numeric, integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pItemlocSeries ALIAS FOR $3;
  pGlDistTS ALIAS FOR $4;
  _woNumber TEXT;
  _invhistid INTEGER;
  _itemlocSeries INTEGER;
  _qty NUMERIC;
  _cost NUMERIC := 0;

BEGIN

  _itemlocSeries := 0;
  
  IF ( SELECT (
         CASE WHEN (womatl_qtyreq >= 0) THEN
           womatl_qtyiss < pQty
         ELSE
           womatl_qtyiss > pQty
         END )
       FROM womatl
       WHERE ( womatl_id=pWomatlid ) ) THEN
    RETURN pItemlocSeries;
  END IF;

  SELECT itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, pQty)
    INTO _qty
    FROM womatl, itemsite
   WHERE((womatl_itemsite_id=itemsite_id)
     AND (womatl_id=pWomatlid));
  IF (NOT FOUND) THEN
    _qty := pQty;
  END IF;

  SELECT formatWoNumber(womatl_wo_id) INTO _woNumber
  FROM womatl
  WHERE (womatl_id=pWomatlid);

  IF (pItemlocSeries = 0) THEN
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  ELSE
    _itemlocSeries = pItemlocSeries;
  END IF;

  -- Get the cost average
  SELECT SUM(invhist_value_before - invhist_value_after) / SUM(invhist_qoh_before - invhist_qoh_after)  * _qty INTO _cost
  FROM invhist, womatlpost, womatl 
  WHERE((womatlpost_womatl_id=womatl_id) 
   AND (womatlpost_invhist_id=invhist_id) 
   AND (invhist_qoh_before > invhist_qoh_after)
   AND (womatl_id=pWomatlId));

  _cost := COALESCE(_cost, 0); -- make sure it's not a null value

  -- Post the transaction
  SELECT postInvTrans( ci.itemsite_id, 'IM', (_qty * -1), 
                       'W/O', 'WO', _woNumber, '',
                       ('Return ' || item_number || ' from Work Order'),
                       getPrjAccntId(wo_prj_id, pc.costcat_wip_accnt_id), cc.costcat_asset_accnt_id, _itemlocSeries, pGlDistTS,
                       -- Cost will be ignored by Standard Cost items sites
                       _cost) INTO _invhistid
    FROM womatl, wo,
         itemsite AS ci, costcat AS cc,
         itemsite AS pi, costcat AS pc,
         item
   WHERE((womatl_itemsite_id=ci.itemsite_id)
     AND (ci.itemsite_costcat_id=cc.costcat_id)
     AND (womatl_wo_id=wo_id)
     AND (wo_itemsite_id=pi.itemsite_id)
     AND (pi.itemsite_costcat_id=pc.costcat_id)
     AND (ci.itemsite_item_id=item_id)
     AND (womatl_id=pWomatlid) );

--  Create linkage to the transaction created
  IF (_invhistid != -1) THEN
    INSERT INTO womatlpost (womatlpost_womatl_id,womatlpost_invhist_id)
                VALUES (pWomatlid,_invhistid);
  END IF;

--  Decrease the parent W/O's WIP value by the value of the returned components
  UPDATE wo
  SET wo_wipvalue = (wo_wipvalue - (CASE WHEN(itemsite_costmethod IN ('A','J'))
                                              THEN _cost
                                         WHEN(itemsite_costmethod='S')
                                              THEN stdcost(itemsite_item_id) * _qty
                                         ELSE 0.0 END )),
      wo_postedvalue = (wo_postedvalue - (CASE WHEN(itemsite_costmethod IN ('A','J'))
                                                    THEN _cost
                                               WHEN(itemsite_costmethod='S')
                                                    THEN stdcost(itemsite_item_id) * _qty
                                               ELSE 0.0 END ))
  FROM womatl, itemsite
  WHERE ( (wo_id=womatl_wo_id)
   AND (womatl_itemsite_id=itemsite_id)
   AND (womatl_id=pWomatlid) );

  UPDATE womatl
  SET womatl_qtyiss = (womatl_qtyiss - pQty),
      womatl_lastreturn = CURRENT_DATE
  WHERE (womatl_id=pWomatlid);

  RETURN _itemlocSeries;

END;

Function: public.returnwomaterial(integer, numeric, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pGlDistTS ALIAS FOR $3;
  _itemlocSeries INTEGER;

BEGIN

  SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
  RETURN returnWoMaterial(pWomatlid, pQty, _itemlocSeries, pGlDistTS);

END;

Function: public.returnwomaterialbatch(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoid ALIAS FOR $1;
  _itemlocSeries INTEGER;
  _woid INTEGER;
  _r RECORD;

BEGIN

  SELECT wo_id INTO _woid
  FROM wo
  WHERE ( (wo_status IN ('E','I'))
   AND (wo_id=pWoid) );

  IF (FOUND) THEN
    SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;

    FOR _r IN SELECT womatl_id, 
                CASE WHEN wo_qtyord >= 0 THEN
                  womatl_qtyiss
                ELSE
                  ((womatl_qtyreq - womatl_qtyiss) * -1)
                END AS qty
              FROM wo, womatl, itemsite
              WHERE ((wo_id=womatl_wo_id)
              AND (womatl_itemsite_id=itemsite_id)
              AND ( (wo_qtyord < 0) OR (womatl_issuemethod IN ('S','M')) )
              AND (womatl_wo_id=pWoid)) LOOP

      IF (_r.qty != 0) THEN
        PERFORM returnWoMaterial(_r.womatl_id, _r.qty, _itemlocSeries, now());
      END IF;

    END LOOP;

--  Reset the W/O Status to E
    UPDATE wo
    SET wo_status='E'
    WHERE (wo_id=pWoid);

    RETURN _itemlocSeries;

  ELSE 
    RETURN -1;
  END IF;

END;

Function: public.reversecashreceipt(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _p RECORD;
  _r RECORD;
  _postToAR NUMERIC;
  _postToMisc NUMERIC;
  _posted_base NUMERIC := 0;
  _posted NUMERIC := 0;
  _sequence INTEGER;
  _aropenid INTEGER;
  _arMemoNumber TEXT;
  _arAccntid INTEGER;
  _closed BOOLEAN;
  _debitAccntid INTEGER;
  _exchGain NUMERIC;
  _comment      TEXT;

BEGIN
  _posted := 0;
  _posted_base := 0;

  SELECT fetchGLSequence() INTO _sequence;

  SELECT accnt_id INTO _arAccntid
  FROM cashrcpt, accnt, salescat
  WHERE ((cashrcpt_salescat_id=salescat_id)
    AND  (salescat_ar_accnt_id=accnt_id)
    AND  (cashrcpt_id=pCashrcptid));
  IF (NOT FOUND) THEN
    SELECT accnt_id INTO _arAccntid
    FROM cashrcpt, accnt
    WHERE ( (findARAccount(cashrcpt_cust_id)=accnt_id)
     AND (cashrcpt_id=pCashrcptid) );
    IF (NOT FOUND) THEN
      RETURN -5;
    END IF;
  END IF;

  SELECT cashrcpt_cust_id, ('Reverse Cash Receipt posting for ' || cust_number||'-'||cust_name) AS custnote,
         cashrcpt_fundstype, cashrcpt_number, cashrcpt_docnumber,
         cashrcpt_distdate, cashrcpt_amount, cashrcpt_discount,
         (cashrcpt_amount / cashrcpt_curr_rate) AS cashrcpt_amount_base,
         (cashrcpt_discount / cashrcpt_curr_rate) AS cashrcpt_discount_base,
         cashrcpt_notes,
         cashrcpt_bankaccnt_id AS bankaccnt_id,
         accnt_id AS prepaid_accnt_id,
         cashrcpt_usecustdeposit,
         cashrcpt_curr_id, cashrcpt_curr_rate INTO _p
  FROM accnt, cashrcpt LEFT OUTER JOIN custinfo ON (cashrcpt_cust_id=cust_id)
  WHERE ( (findPrepaidAccount(cashrcpt_cust_id)=accnt_id)
   AND (cashrcpt_id=pCashrcptid) );
  IF (NOT FOUND) THEN
    RETURN -7;
  END IF;

  IF (_p.cashrcpt_fundstype IN ('A', 'D', 'M', 'V')) THEN
    IF NOT EXISTS(SELECT ccpay_id
                  FROM ccpay
                  WHERE ((ccpay_order_number=CAST(pCashrcptid AS TEXT))
                     AND (ccpay_status IN ('C', 'A')))) THEN
      RETURN -8;
    END IF;
    _debitAccntid := findPrepaidAccount(_p.cashrcpt_cust_id);
  ELSE
    SELECT accnt_id INTO _debitAccntid
    FROM cashrcpt, bankaccnt, accnt
    WHERE ( (cashrcpt_bankaccnt_id=bankaccnt_id)
     AND (bankaccnt_accnt_id=accnt_id)
     AND (cashrcpt_id=pCashrcptid) );
    IF (NOT FOUND) THEN
      RETURN -6;
    END IF;
  END IF;

--  Determine the amount to post to A/R Open Items
  SELECT COALESCE(SUM(cashrcptitem_amount),0) INTO _postToAR
  FROM cashrcptitem JOIN aropen ON (aropen_id=cashrcptitem_aropen_id)
  WHERE ((cashrcptitem_cashrcpt_id=pCashrcptid)
   AND (cashrcptitem_applied));
  IF (NOT FOUND) THEN
    _postToAR := 0;
  END IF;

--  Determine the amount to post to Misc. Distributions
  SELECT COALESCE(SUM(cashrcptmisc_amount),0) INTO _postToMisc
  FROM cashrcptmisc
  WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid);
  IF (NOT FOUND) THEN
    _postToMisc := 0;
  END IF;

--  Check to see if the C/R is over applied
  IF ((_postToAR + _postToMisc) > _p.cashrcpt_amount) THEN
    RETURN -1;
  END IF;

--  Check to see if the C/R is positive amount
  IF (_p.cashrcpt_amount <= 0) THEN
    RETURN -2;
  END IF;

--  Distribute A/R Applications
  FOR _r IN SELECT aropen_id, aropen_doctype, aropen_docnumber, aropen_docdate,
                   aropen_duedate, aropen_curr_id, aropen_curr_rate,
                   round(aropen_amount - aropen_paid, 2) <=
                      round(aropen_paid + 
                      currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,abs(cashrcptitem_amount + cashrcptitem_discount),_p.cashrcpt_distdate),2)
                               AS closed,
                   cashrcptitem_id, cashrcptitem_amount, cashrcptitem_discount,
                   (cashrcptitem_amount / _p.cashrcpt_curr_rate) AS cashrcptitem_amount_base,
                   (cashrcptitem_discount / _p.cashrcpt_curr_rate) AS cashrcptitem_discount_base,
                   round(aropen_paid - 
                      currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,abs(cashrcptitem_amount),_p.cashrcpt_distdate),2) AS new_paid,
                   round(currToCurr(_p.cashrcpt_curr_id, aropen_curr_id,abs(cashrcptitem_discount),_p.cashrcpt_distdate),2) AS new_discount
            FROM cashrcptitem JOIN aropen ON (cashrcptitem_aropen_id=aropen_id)
            WHERE ((cashrcptitem_cashrcpt_id=pCashrcptid)
              AND (cashrcptitem_applied)) LOOP

--  Handle discount 
    IF (_r.cashrcptitem_discount_base > 0) THEN
      PERFORM reverseCashReceiptDisc(_r.cashrcptitem_id, pJournalNumber);
    END IF;
     
--  Update the aropen item to post the paid amount
    UPDATE aropen
    SET aropen_paid = _r.new_paid - _r.new_discount,
        aropen_open = TRUE,
        aropen_closedate = NULL
    WHERE (aropen_id=_r.aropen_id);

--  Cache the running amount posted
    _posted_base := _posted_base + _r.cashrcptitem_amount_base;
    _posted := _posted + _r.cashrcptitem_amount;

--  Record the cashrcpt application
    IF (_r.aropen_doctype IN ('I','D')) THEN
      INSERT INTO arapply
      ( arapply_cust_id,
        arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
        arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
        arapply_fundstype, arapply_refnumber, arapply_reftype, arapply_ref_id,
        arapply_applied, arapply_closed,
        arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_username,
        arapply_curr_id
       )
      VALUES
      ( _p.cashrcpt_cust_id,
        -1, 'K', _p.cashrcpt_number,
        _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
        _p.cashrcpt_fundstype, _p.cashrcpt_docnumber, 'CRA', _r.cashrcptitem_id,
        (round(_r.cashrcptitem_amount, 2) * -1.0), _r.closed,
        CURRENT_DATE, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), _p.cashrcpt_curr_id );
    ELSE
      INSERT INTO arapply
      ( arapply_cust_id,
        arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
        arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
        arapply_fundstype, arapply_refnumber, arapply_reftype, arapply_ref_id,
        arapply_applied, arapply_closed, arapply_postdate, arapply_distdate,
        arapply_journalnumber, arapply_username, arapply_curr_id )
      VALUES
      ( _p.cashrcpt_cust_id,
        _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
        -1, 'R', _p.cashrcpt_number,
        '', '', 'CRA', _r.cashrcptitem_id,
        (round(abs(_r.cashrcptitem_amount), 2) * -1.0), _r.closed,
        CURRENT_DATE, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), _p.cashrcpt_curr_id );
    END IF;

    _exchGain := arCurrGain(_r.aropen_id,_p.cashrcpt_curr_id, abs(_r.cashrcptitem_amount),
                           _p.cashrcpt_distdate);

    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                        (_r.aropen_doctype || '-' || _r.aropen_docnumber),
                        CASE WHEN _r.aropen_doctype != 'R' THEN _arAccntid
                        ELSE findDeferredAccount(_p.cashrcpt_cust_id) END, 
                        (round(_r.cashrcptitem_amount_base + _exchGain, 2) * -1.0),
                        _p.cashrcpt_distdate, _p.custnote );

    IF (_exchGain <> 0) THEN
        PERFORM insertIntoGLSeries(_sequence, 'A/R', 'CR',
               _r.aropen_doctype || '-' || _r.aropen_docnumber,
               getGainLossAccntId(
               CASE WHEN _r.aropen_doctype != 'R' THEN _arAccntid
               ELSE findDeferredAccount(_p.cashrcpt_cust_id) END
               ), round(_exchGain, 2),
               _p.cashrcpt_distdate, _p.custnote);

    END IF;

  END LOOP;

--  Distribute Misc. Applications
  FOR _r IN SELECT cashrcptmisc_id, cashrcptmisc_accnt_id, cashrcptmisc_amount,
                   (cashrcptmisc_amount / _p.cashrcpt_curr_rate) AS cashrcptmisc_amount_base,
                   cashrcptmisc_notes
            FROM cashrcptmisc
            WHERE (cashrcptmisc_cashrcpt_id=pCashrcptid)  LOOP

--  Cache the running amount posted
    _posted_base := (_posted_base + _r.cashrcptmisc_amount_base);
    _posted := (_posted + _r.cashrcptmisc_amount);

--  Record the cashrcpt application
    INSERT INTO arapply
    ( arapply_cust_id,
      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
      arapply_fundstype, arapply_refnumber,
      arapply_applied, arapply_closed,
      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_username,
      arapply_curr_id, arapply_reftype, arapply_ref_id )
    VALUES
    ( _p.cashrcpt_cust_id,
      -1, 'K', '',
      -1, 'Misc.', '',
      _p.cashrcpt_fundstype, _p.cashrcpt_docnumber,
      (round(_r.cashrcptmisc_amount, 2) * -1.0), TRUE,
      CURRENT_DATE, _p.cashrcpt_distdate, pJournalNumber, getEffectiveXtUser(), 
      _p.cashrcpt_curr_id, 'CRD', _r.cashrcptmisc_id );

    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR', _r.cashrcptmisc_notes,
                                _r.cashrcptmisc_accnt_id,
                                (round(_r.cashrcptmisc_amount_base, 2) * -1.0),
                                _p.cashrcpt_distdate, _p.custnote );

  END LOOP;

--  Post any remaining Cash to an A/R Debit Memo
--  this credit memo may absorb an occasional currency exchange rounding error
  IF (round(_posted_base, 2) < round(_p.cashrcpt_amount_base, 2)) THEN
    _comment := ('Unapplied from ' || _p.cashrcpt_fundstype || '-' || _p.cashrcpt_docnumber);
    PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                                _comment,
                                _p.prepaid_accnt_id,
                                ((round(_p.cashrcpt_amount_base, 2) - round(_posted_base, 2)) * -1.0),
                                _p.cashrcpt_distdate, _p.custnote );
    SELECT fetchArMemoNumber() INTO _arMemoNumber;
    -- Post A/R Debit Memo
    SELECT createARDebitMemo(NULL, _p.cashrcpt_cust_id, pJournalNumber, _arMemoNumber, '',
                              _p.cashrcpt_distdate, (_p.cashrcpt_amount - _posted),
                              _comment, -1, -1, -1, _p.cashrcpt_distdate, -1, NULL, 0,
                              _p.cashrcpt_curr_id) INTO _aropenid;
    -- Create Cash Receipt Item to capture posting
    INSERT INTO cashrcptitem
      ( cashrcptitem_cashrcpt_id, cashrcptitem_aropen_id, cashrcptitem_amount )
    VALUES
      ( pCashrcptid, _aropenid, ((_p.cashrcpt_amount - _posted) * 1.0) );

  ELSIF (round(_posted_base, 2) > round(_p.cashrcpt_amount_base, 2)) THEN
    PERFORM insertIntoGLSeries(_sequence, 'A/R', 'CR',
                   'Currency Exchange Rounding - ' || _p.cashrcpt_docnumber,
                   getGainLossAccntId(_debitAccntid),
                   ((round(_posted_base, 2) - round((_p.cashrcpt_amount_base + _p.cashrcpt_discount_base), 2)) * 1.0),
                   _p.cashrcpt_distdate, _p.custnote);
  END IF;

--  Debit Cash
  PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
                    (_p.cashrcpt_fundstype || '-' || _p.cashrcpt_docnumber),
                     _debitAccntid, round(_p.cashrcpt_amount_base, 2),
                     _p.cashrcpt_distdate,
                     _p.custnote );

  PERFORM postGLSeries(_sequence, pJournalNumber);

--  Update and void the posted cashrcpt
  UPDATE cashrcpt SET cashrcpt_posted=FALSE,
                      cashrcpt_posteddate=NULL,
                      cashrcpt_postedby=NULL,
                      cashrcpt_void=TRUE
  WHERE (cashrcpt_id=pCashrcptid);

  RETURN 1;

END;

Function: public.reversecashreceiptdisc(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCashrcptItemId ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _r RECORD;
  _t RECORD;
  _v RECORD;
  _ardiscountid INTEGER;
  _arMemoNumber TEXT;
  _arAccntid INTEGER;
  _discountAccntid INTEGER;
  _comment      TEXT;
  _discprcnt NUMERIC;
  _check INTEGER;

BEGIN

    -- Fetch base records for processing
    SELECT aropen_id, aropen_doctype, aropen_amount,
           cashrcptitem_discount,
           cashrcpt_cust_id, cashrcpt_distdate, cashrcpt_applydate,
           cashrcpt_curr_id, cashrcpt_fundstype, cashrcpt_docnumber,
           round(currToCurr(cashrcpt_curr_id, aropen_curr_id, cashrcptitem_discount, cashrcpt_distdate),2) AS aropen_discount
      INTO _r
    FROM cashrcptitem 
      JOIN cashrcpt ON (cashrcptitem_cashrcpt_id=cashrcpt_id)
      JOIN aropen ON ( (aropen_id=cashrcptitem_aropen_id) AND (aropen_doctype IN ('I', 'D')) )
    WHERE (cashrcptitem_id=pCashrcptItemId);

    -- Get discount account
    _discountAccntid := findardiscountaccount(_r.cashrcpt_cust_id);
  
    IF (_r.cashrcptitem_discount > 0) THEN
      --  Determine discount percentage
      _discprcnt := _r.aropen_discount / _r.aropen_amount;

      SELECT fetchArMemoNumber() INTO _arMemoNumber;
      _comment := 'Discount Credit Reversal from ' || _r.cashrcpt_fundstype || '-' || _r.cashrcpt_docnumber;

      -- Create misc debit memo record
      _ardiscountid := nextval('aropen_aropen_id_seq');
      INSERT INTO aropen (
        aropen_id, aropen_docdate, aropen_duedate, aropen_doctype, 
        aropen_docnumber, aropen_curr_id, aropen_posted, aropen_amount ) 
      VALUES ( 
        _ardiscountid, _r.cashrcpt_distdate, _r.cashrcpt_distdate, 'D', 
        _arMemoNumber, _r.cashrcpt_curr_id, false,_r.cashrcptitem_discount);
        
      IF (fetchMetricBool('CreditTaxDiscount')) THEN
        --  proportional tax credits calculated and implemented for the debit memo generated by the discount
        IF (_r.aropen_doctype  = 'I') THEN
          -- Tax for invoices
          SELECT aropen_cobmisc_id AS invcheadid, 
                 invchead_curr_id, 
                 invchead_invcdate INTO _t
          FROM aropen
            LEFT OUTER JOIN invchead ON (aropen_cobmisc_id = invchead_id) 
            LEFT OUTER JOIN invcitem ON (invchead_id = invcitem_invchead_id)
          WHERE aropen_id = _r.aropen_id;

          FOR _v IN SELECT tax_sales_accnt_id,
                           tax_id, 
                           round(sum(taxdetail_tax), 2) AS tax,
                           currToBase(_t.invchead_curr_id, round(sum(taxdetail_tax), 2), _t.invchead_invcdate) AS taxbasevalue
          FROM tax 
            JOIN calculateTaxDetailSummary('I', _t.invcheadid, 'T') ON (taxdetail_tax_id=tax_id)
            GROUP BY tax_id, tax_sales_accnt_id 
          LOOP
            INSERT INTO aropentax(
              taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
              taxhist_percent, taxhist_amount, taxhist_tax, 
              taxhist_docdate, taxhist_basis)
            VALUES (
              _ardiscountid, getadjustmenttaxtypeid(), _v.tax_id, 
              0.00, 0.00, (round((_v.tax * _discprcnt), 2)), 
              _r.cashrcpt_distdate, 0.00);
          END LOOP;

        ELSIF (_r.aropen_doctype  = 'D') THEN
          -- Tax for debit memos
          INSERT INTO aropentax(
            taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
            taxhist_percent, taxhist_amount, taxhist_tax, 
            taxhist_docdate, taxhist_basis)
          SELECT
            _ardiscountid, taxhist_taxtype_id, taxhist_tax_id, 
            0.00, 0.00, (round((taxhist_tax * _discprcnt), 2)),  
            _r.cashrcpt_distdate, 0.00
          FROM aropentax
          WHERE (taxhist_parent_id=_r.aropen_id);
              
        END IF;
      END IF; -- End taxes

      -- Create debit memo for discount
      SELECT createARDebitMemo(_ardiscountid, _r.cashrcpt_cust_id, pJournalNumber, _arMemoNumber, '',
                                _r.cashrcpt_distdate, _r.cashrcptitem_discount,
                                _comment, -1, -1, _discountAccntid, _r.cashrcpt_distdate,
                                -1, NULL, 0, _r.cashrcpt_curr_id) INTO _ardiscountid;

    END IF; -- End handle Discount

    RETURN 1;

END;

Function: public.reverseglseries(integer, date, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSequence ALIAS FOR $1;
  pDistDate ALIAS FOR $2;
  pNotes ALIAS FOR $3;
  _sequence INTEGER := fetchGLSequence();	
  _journal INTEGER;

BEGIN

  IF (SELECT COUNT(gltrans_sequence) > 0 FROM gltrans WHERE gltrans_sequence = pSequence) THEN
    SELECT fetchJournalNumber(jrnluse_use) INTO _journal
    FROM gltrans
      JOIN jrnluse ON (gltrans_journalnumber=jrnluse_number)
    WHERE (gltrans_sequence=pSequence)
    LIMIT 1;
  
    INSERT INTO gltrans (gltrans_created, gltrans_posted, gltrans_exported,
                         gltrans_date, gltrans_sequence, gltrans_accnt_id,
                         gltrans_source, gltrans_docnumber, gltrans_misc_id,
                         gltrans_amount, gltrans_notes, gltrans_journalnumber,
                         gltrans_doctype)
                 SELECT  CURRENT_TIMESTAMP, FALSE, FALSE,
                         pDistDate, _sequence, gltrans_accnt_id,
                         gltrans_source, gltrans_docnumber, gltrans_misc_id,
                         (gltrans_amount * -1), pNotes, _journal,
                         gltrans_doctype
                    FROM gltrans
                   WHERE (gltrans_sequence=pSequence);

    PERFORM postIntoTrialBalance(_sequence);
  ELSE
    SELECT fetchJournalNumber(jrnluse_use) INTO _journal
    FROM sltrans
      JOIN jrnluse ON (sltrans_journalnumber=jrnluse_number)
    WHERE (sltrans_sequence=pSequence)
    LIMIT 1;
    
    INSERT INTO sltrans (sltrans_created, sltrans_posted,
                         sltrans_date, sltrans_sequence, sltrans_accnt_id,
                         sltrans_source, sltrans_docnumber, sltrans_misc_id,
                         sltrans_amount, sltrans_notes, sltrans_journalnumber,
                         sltrans_doctype)
                 SELECT  CURRENT_TIMESTAMP, FALSE,
                         pDistDate, _sequence, sltrans_accnt_id,
                         sltrans_source, sltrans_docnumber, sltrans_misc_id,
                         (sltrans_amount * -1), pNotes, _journal,
                         sltrans_doctype
                    FROM sltrans
                   WHERE (sltrans_sequence=pSequence);
  END IF;

  RETURN _journal;
END;

Function: public.revokeallmodulecmnttypesource(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmnttypeid ALIAS FOR $1;
  pModuleName ALIAS FOR $2;

BEGIN

  DELETE FROM cmnttypesource
  WHERE (cmnttypesource_id IN ( SELECT cmnttypesource_id
                                FROM cmnttypesource, source
                                WHERE ( (cmnttypesource_source_id=source_id)
                                  AND (cmnttypesource_cmnttype_id=pCmnttypeid)
                                  AND (source_module=pModuleName) ) ) );

  RETURN 1;

END;

Function: public.revokeallmodulepriv(text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pModuleName ALIAS FOR $2;

BEGIN

  DELETE FROM usrpriv
  WHERE (usrpriv_id IN ( SELECT usrpriv_id
                         FROM usrpriv, priv
                         WHERE ( (usrpriv_priv_id=priv_id)
                          AND (usrpriv_username=pUsername)
                          AND (priv_module=pModuleName) ) ) );

  NOTIFY "usrprivUpdated";

  RETURN 1;

END;

Function: public.revokeallmoduleprivgroup(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGrpid ALIAS FOR $1;
  pModuleName ALIAS FOR $2;

BEGIN

  DELETE FROM grppriv
  WHERE (grppriv_id IN ( SELECT grppriv_id
                         FROM grppriv, priv
                         WHERE ( (grppriv_priv_id=priv_id)
                          AND (grppriv_grp_id=pGrpid)
                          AND (priv_module=pModuleName) ) ) );

  RETURN 1;

END;

Function: public.revokecmnttypesource(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmnttypeid ALIAS FOR $1;
  pSourceid ALIAS FOR $2;

BEGIN

  DELETE FROM cmnttypesource
  WHERE ( (cmnttypesource_cmnttype_id=pCmnttypeid)
    AND (cmnttypesource_source_id=pSourceid) );

  RETURN TRUE;

END;

Function: public.revokegroup(text, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pGrpid ALIAS FOR $2;

BEGIN

  DELETE FROM usrgrp
  WHERE ( (usrgrp_username=pUsername)
   AND (usrgrp_grp_id=pGrpid) );

  RETURN TRUE;

END;

Function: public.revokepriv(text, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrivid ALIAS FOR $2;

BEGIN

  DELETE FROM usrpriv
  WHERE ( (usrpriv_username=pUsername)
   AND (usrpriv_priv_id=pPrivid) );

  NOTIFY "usrprivUpdated";

  RETURN TRUE;

END;

Function: public.revokepriv(text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrivname ALIAS FOR $2;

BEGIN

  DELETE FROM usrpriv
  WHERE ( (usrpriv_username=pUsername)
   AND (usrpriv_priv_id IN (SELECT priv_id
                              FROM priv
                             WHERE priv_name=pPrivname) ));

  NOTIFY "usrprivUpdated";

  RETURN TRUE;

END;

Function: public.revokeprivgroup(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGrpid ALIAS FOR $1;
  pPrivid ALIAS FOR $2;

BEGIN

  DELETE FROM grppriv
  WHERE ( (grppriv_grp_id=pGrpid)
   AND (grppriv_priv_id=pPrivid) );

  NOTIFY "usrprivUpdated";

  RETURN TRUE;

END;

Function: public.rollupactualcost(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pItemid ALIAS FOR $1;

BEGIN
    RETURN rollUpSorACost(pitemid, TRUE);
END;

Function: public.rollupsoracost(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid	ALIAS FOR $1;
  pActual	ALIAS FOR $2;
  _counter INTEGER;
  _setid INTEGER;
  _consumers RECORD;

BEGIN

  _counter := 0;

  SELECT indentedWhereUsed(pItemid) INTO _setid;

  FOR _consumers IN SELECT bomwork_item_id
                    FROM bomwork
                    WHERE (bomwork_set_id=_setid)
                    ORDER BY bomwork_level LOOP
    PERFORM updateSorACost( _consumers.bomwork_item_id, costelem_type, TRUE,
			    lowerCost(_consumers.bomwork_item_id,
				      costelem_type, pActual),
			    pActual )
    FROM costelem
    WHERE (costelem_sys);

    PERFORM updateLowerUserCosts(_consumers.bomwork_item_id, pActual);

    _counter := _counter + 1;

  END LOOP;

  PERFORM deleteBOMWorkset(_setid);

  RETURN _counter;

END;

Function: public.rollupstandardcost(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pItemid ALIAS FOR $1;

BEGIN
    RETURN rollUpSorACost(pItemid, FALSE);
END;

Function: public.roundcost(numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pCost ALIAS FOR $1;

  _scale INTEGER;

BEGIN
  IF (_pCost IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT locale_cost_scale INTO _scale
  FROM locale, usr
  WHERE ((usr_locale_id=locale_id)
     AND (usr_username=getEffectiveXtUser()));

  RETURN ROUND(_pCost, _scale);

END;

Function: public.roundqty(boolean, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _fractional ALIAS FOR $1;
  _qty ALIAS FOR $2;
  _scale INTEGER;

BEGIN
  SELECT locale_qty_scale INTO _scale
  FROM locale, usr
  WHERE ((usr_locale_id=locale_id) AND (usr_username=getEffectiveXtUser()));

  IF (_fractional) THEN
    RETURN ROUND(_qty, _scale);
  ELSE
    IF (TRUNC(_qty) < ROUND(_qty, _scale)) THEN
      RETURN (TRUNC(_qty) + 1);
    ELSE
      RETURN TRUNC(_qty);
    END IF;
  END IF;
END;

Function: public.roundsale(numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _pSale ALIAS FOR $1;
  _scale INTEGER;

BEGIN
  IF (_pSale IS NULL) THEN
    RETURN NULL;
  END IF;

  SELECT locale_salesprice_scale INTO _scale
  FROM locale, usr
  WHERE ((usr_locale_id=locale_id)
     AND (usr_username=getEffectiveXtUser()));

  RETURN ROUND(_pSale, _scale);

END;

Function: public.roundup(numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pValue ALIAS FOR $1;
  _checkValue integer;

BEGIN

  _checkValue := pValue::integer;

  IF (_checkValue::numeric < pValue) THEN
    RETURN (_checkValue + 1)::numeric;
  ELSE
    RETURN _checkValue::numeric;
  END IF;

END;

Function: public.saveaddr(integer, text, text, text, text, text, text, text, text, boolean, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAddrId ALIAS FOR $1;
  pNumber ALIAS FOR $2;
  pAddr1 ALIAS FOR $3;
  pAddr2 ALIAS FOR $4;
  pAddr3 ALIAS FOR $5;
  pCity ALIAS FOR $6;
  pState ALIAS FOR $7;
  pPostalCode ALIAS FOR $8;
  pCountry ALIAS FOR $9;
  pActive ALIAS FOR $10;
  pNotes ALIAS FOR $11;
  pFlag ALIAS FOR $12;
  _addrId INTEGER;
  _addrNumber INTEGER;
  _flag TEXT;
  _p RECORD;
  _cnt INTEGER;
  _notes TEXT;

BEGIN
  --Validate
  IF ((pFlag IS NULL) OR (pFlag = '') OR (pFlag = 'CHECK') OR (pFlag = 'CHANGEONE') OR (pFlag = 'CHANGEALL')) THEN
    IF (pFlag='') THEN
      _flag := 'CHECK';
    ELSE
      _flag := COALESCE(pFlag,'CHECK');
    END IF;
  ELSE
	RAISE EXCEPTION 'Invalid Flag (%). Valid flags are CHECK, CHANGEONE or CHANGEALL', pFlag;
  END IF;

  _notes := COALESCE(pNotes,'');
  
  --If there is nothing here, get out
  IF ( (pNumber = '' OR pNumber IS NULL)
    AND (pAddr1 = '' OR pAddr1 IS NULL)
    AND (pAddr2 = '' OR pAddr2 IS NULL)
    AND (pAddr3 = '' OR pAddr3 IS NULL)
    AND (pCity = '' OR pCity IS NULL)
    AND (pState = '' OR pState IS NULL)
    AND (pPostalCode = '' OR pPostalCode IS NULL)
    AND (pCountry = '' OR pCountry IS NULL) ) THEN
    RETURN NULL;
  
  END IF;
  
  _addrId := COALESCE(pAddrId,-1);

  --If we have an ID see if anything has changed, if not get out
  IF (_addrId >= 0) THEN
    SELECT * FROM addr INTO _p
    WHERE ((pAddrId=addr_id)
    AND (COALESCE(pNumber,addr_number)=addr_number)
    AND (COALESCE(pAddr1, '')=COALESCE(addr_line1, ''))
    AND (COALESCE(pAddr2, '')=COALESCE(addr_line2, ''))
    AND (COALESCE(pAddr3, '')=COALESCE(addr_line3, ''))
    AND (COALESCE(pCity, '')=COALESCE(addr_city, ''))
    AND (COALESCE(pState, '')=COALESCE(addr_state, ''))
    AND (COALESCE(pPostalCode, '')=COALESCE(addr_postalcode, ''))
    AND (COALESCE(pCountry, '')=COALESCE(addr_country, ''))
    AND (pActive=addr_active)
    AND (_notes=COALESCE(addr_notes,'')));
    IF (FOUND) THEN
      RETURN _addrId;
    END IF;
  END IF;
 
  --Check to see if duplicate address exists

    SELECT addr_id, addr_notes INTO _p
    FROM addr 
    WHERE ((_addrId <> addr_id)
    AND  (COALESCE(UPPER(addr_line1),'') = COALESCE(UPPER(pAddr1),''))
    AND  (COALESCE(UPPER(addr_line2),'') = COALESCE(UPPER(pAddr2),''))
    AND  (COALESCE(UPPER(addr_line3),'') = COALESCE(UPPER(pAddr3),''))
    AND  (COALESCE(UPPER(addr_city),'') = COALESCE(UPPER(pCity),''))
    AND  (COALESCE(UPPER(addr_state),'') = COALESCE(UPPER(pState),''))
    AND  (COALESCE(UPPER(addr_postalcode),'') = COALESCE(UPPER(pPostalcode),''))
    AND  (COALESCE(UPPER(addr_country),'') = COALESCE(UPPER(pCountry),'')));
    IF (FOUND) THEN
	--Note:  To prevent overwriting of existing notes, the application
	--needs to load any existing notes for a matching address before altering them.
	IF (_notes <> _p.addr_notes) THEN
		UPDATE addr 
		SET addr_notes=addr_notes || '
' || _notes
		WHERE addr_id=_p.addr_id;
	END IF;
        RETURN _p.addr_id;  --A matching address exits
    END IF;
 
  IF (_addrId < 0) THEN
    _flag := 'CHANGEONE';
  END IF;

  IF (_flag = 'CHECK') THEN
    IF addrUseCount(_addrId) > 1 THEN
      RETURN -2;
    ELSIF (SELECT COUNT(addr_id)=0 FROM addr WHERE (addr_id=_addrId)) THEN
      _flag := 'CHANGEONE';
    ELSE
      _flag := 'CHANGEALL';
    END IF;
  END IF;

  IF (_flag = 'CHANGEALL') THEN
    _addrNumber := pNumber;
    IF (_addrNumber IS NULL) THEN
      SELECT addr_number INTO _addrNumber
        FROM addr
       WHERE(addr_id = _addrId);
      IF (_addrNumber IS NULL) THEN
        _addrNumber := fetchNextNumber('AddressNumber');
      END IF;
    END IF;
   
    UPDATE addr SET
      addr_line1 = pAddr1, addr_line2 = pAddr2, addr_line3 = pAddr3,
      addr_city = pCity, addr_state = pState,
      addr_postalcode = pPostalcode, addr_country = pCountry,
      addr_active = pActive, addr_notes = pNotes
    WHERE addr_id = _addrId;
    RETURN _addrId;

  ELSE
    SELECT NEXTVAL('addr_addr_id_seq') INTO _addrId;

    _addrNumber := COALESCE(pNumber::text,fetchNextNumber('AddressNumber'));

    INSERT INTO addr ( addr_id, addr_number,
    addr_line1, addr_line2, addr_line3, 
    addr_city, addr_state, addr_postalcode, addr_country, 
    addr_active, addr_notes  
    ) VALUES ( _addrId, _addrNumber,
    pAddr1, pAddr2, pAddr3, 
    pCity, pState, pPostalcode, pCountry,
    pActive, _notes);
    RETURN _addrId;
	
  END IF;
END;

Function: public.saveaddr(integer, text, text, text, text, text, text, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAddrId ALIAS FOR $1;
  pNumber ALIAS FOR $2;
  pAddr1 ALIAS FOR $3;
  pAddr2 ALIAS FOR $4;
  pAddr3 ALIAS FOR $5;
  pCity ALIAS FOR $6;
  pState ALIAS FOR $7;
  pPostalCode ALIAS FOR $8;
  pCountry ALIAS FOR $9;
  pFlag ALIAS FOR $10;
  _returnVal INTEGER;

BEGIN
 
  SELECT saveAddr(pAddrId,pNumber, pAddr1,pAddr2,pAddr3,pCity,pState,pPostalCode,pCountry,true,'',pFlag) INTO _returnVal;
  
  RETURN _returnVal;

END;

Function: public.savealarm(integer, text, date, time without time zone, integer, text, boolean, text, boolean, text, boolean, text, text, integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pAlarmId ALIAS FOR $1;
  pAlarmNumber ALIAS FOR $2;
  pDate ALIAS FOR $3;
  pTime ALIAS FOR $4;
  pOffset ALIAS FOR $5;
  pQualifier ALIAS FOR $6;
  pEvent ALIAS FOR $7;
  pEventRecipient ALIAS FOR $8;
  pEmail ALIAS FOR $9;
  pEmailRecipient ALIAS FOR $10;
  pSysmsg ALIAS FOR $11;
  pSysmsgRecipient ALIAS FOR $12;
  pSource ALIAS FOR $13;
  pSourceId ALIAS FOR $14;
  pFlag ALIAS FOR $15;
  _alarmId INTEGER;
  _alarmNumber TEXT;
  _alarmTime TIMESTAMP;
  _alarmInterval INTERVAL;
  _alarmTrigger TIMESTAMP;
  _isNew BOOLEAN;
  _flag TEXT;
  _alarmCount INTEGER := 0;
  _debug BOOLEAN := false;

BEGIN
  IF (_debug) THEN
    RAISE NOTICE 'pAlarmId = %', pAlarmId;
    RAISE NOTICE 'pAlarmNumber = %', pAlarmNumber;
    RAISE NOTICE 'pDate = %', pDate;
    RAISE NOTICE 'pTime = %', pTime;
    RAISE NOTICE 'pOffset = %', pOffset;
    RAISE NOTICE 'pQualifier = %', pQualifier;
    RAISE NOTICE 'pEvent = %', pEvent;
    RAISE NOTICE 'pEventRecipient = %', pEventRecipient;
    RAISE NOTICE 'pEmail = %', pEmail;
    RAISE NOTICE 'pEmailRecipient = %', pEmailRecipient;
    RAISE NOTICE 'pSysmsg = %', pSysmsg;
    RAISE NOTICE 'pSysmsgRecipient = %', pSysmsgRecipient;
    RAISE NOTICE 'pSource = %', pSource;
    RAISE NOTICE 'pSourceId = %', pSourceId;
    RAISE NOTICE 'pFlag = %', pFlag;
  END IF;
  --Validate
  IF ((pFlag IS NULL) OR (pFlag = '') OR (pFlag = 'CHECK') OR (pFlag = 'CHANGEONE') OR (pFlag = 'CHANGEALL')) THEN
    IF (pFlag='') THEN
      _flag := 'CHECK';
    ELSE
      _flag := COALESCE(pFlag,'CHECK');
    END IF;
  ELSE
	RAISE EXCEPTION 'Invalid Flag (%). Valid flags are CHECK, CHANGEONE or CHANGEALL', pFlag;
  END IF;
  
  --If there is nothing here get out
  IF ( (pAlarmId IS NULL OR pAlarmId = -1)
	AND (pOffset IS NULL)
        AND (pSourceId IS NULL)
	AND (COALESCE(pQualifier, '') = '')
	AND (COALESCE(pEventRecipient, '') = '')
	AND (COALESCE(pEmailRecipient, '') = '')
	AND (COALESCE(pSysmsgRecipient, '') = '')
	AND (COALESCE(pSource, '') = '') ) THEN
	
	RETURN NULL;

  END IF;
  
  IF (pAlarmId IS NULL OR pAlarmId = -1) THEN 
    _isNew := true;
    _alarmId := nextval('alarm_alarm_id_seq');
    _alarmNumber := fetchNextNumber('AlarmNumber');
  ELSE
    SELECT COUNT(alarm_id) INTO _alarmCount
      FROM alarm
      WHERE ((alarm_id=pAlarmId)
      AND (alarm_source=pSource)
      AND (alarm_source_id=pSourceId));

    -- ask whether new or update if name changes
    -- but only if this isn't a new record with a pre-allocated id
    IF (_alarmCount < 1 AND _flag = 'CHECK') THEN
      IF (EXISTS(SELECT alarm_id
                 FROM alarm
                 WHERE (alarm_id=pAlarmId))) THEN
        RETURN -10;
      ELSE
        _isNew := true;
        _alarmNumber := fetchNextNumber('AlarmNumber');
      END IF;
    ELSIF (_flag = 'CHANGEONE') THEN
      _isNew := true;
      _alarmId := nextval('alarm_alarm_id_seq');
      _alarmNumber := fetchNextNumber('AlarmNumber');
    END IF;
  END IF;

  _alarmNumber := COALESCE(_alarmNumber,pAlarmNumber,fetchNextNumber('AlarmNumber'));

  _alarmTime := COALESCE(pDate, CURRENT_DATE) + COALESCE(pTime, CURRENT_TIME);
  IF (COALESCE(pOffset, 0) > 0) THEN
    _alarmInterval := CASE WHEN (pQualifier IN ('MB', 'MA')) THEN CAST(pOffset AS TEXT) || ' minutes'
                           WHEN (pQualifier IN ('HB', 'HA')) THEN CAST(pOffset AS TEXT) || ' hours'
                           WHEN (pQualifier IN ('DB', 'DA')) THEN CAST(pOffset AS TEXT) || ' days'
                           ELSE ''
                     END;
    _alarmTrigger := CASE WHEN (pQualifier IN ('MB', 'HB', 'DB')) THEN _alarmTime - _alarmInterval 
                          WHEN (pQualifier IN ('MA', 'HA', 'DA')) THEN _alarmTime + _alarmInterval
                          ELSE _alarmTime
                     END; 
  ELSE
    _alarmTrigger := _alarmTime;
  END IF;

  IF (_isNew) THEN
    _alarmId := COALESCE(_alarmId,pAlarmId,nextval('alarm_alarm_id_seq'));
 
    INSERT INTO alarm (
      alarm_id,alarm_number,
      alarm_event, alarm_email, alarm_sysmsg, alarm_trigger,
      alarm_time, alarm_time_offset, alarm_time_qualifier,
      alarm_creator, alarm_event_recipient, alarm_email_recipient, alarm_sysmsg_recipient,
      alarm_source, alarm_source_id )
    VALUES (
      _alarmId, _alarmNumber,
      pEvent, pEmail, pSysmsg, _alarmTrigger,
      _alarmTime, pOffset, pQualifier,
      getEffectiveXtUser(), pEventRecipient, pEmailRecipient, pSysmsgRecipient,
      pSource, pSourceId );

    RETURN _alarmId;

  ELSE
    UPDATE alarm SET
      alarm_number=_alarmNumber,
      alarm_event=COALESCE(pEvent, alarm_event),
      alarm_email=COALESCE(pEmail, alarm_event),
      alarm_sysmsg=COALESCE(pSysmsg, alarm_event),
      alarm_trigger=_alarmTrigger,
      alarm_time=_alarmTime,
      alarm_time_offset=COALESCE(pOffset, alarm_time_offset),
      alarm_time_qualifier=COALESCE(pQualifier, alarm_time_qualifier),
      alarm_event_recipient=COALESCE(pEventRecipient, alarm_event_recipient),
      alarm_email_recipient=COALESCE(pEmailRecipient, alarm_email_recipient),
      alarm_sysmsg_recipient=COALESCE(pSysmsgRecipient, alarm_sysmsg_recipient)
    WHERE (alarm_id=pAlarmId);
    
    RETURN pAlarmId;

  END IF;
END;

Function: public.savebomhead(integer, text, date, text, numeric, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevision ALIAS FOR $2;
  pRevisionDate ALIAS FOR $3;
  pDocumentNumber ALIAS FOR $4;
  pBatchSize ALIAS FOR $5;
  pRequiredQtyPer ALIAS FOR $6;
  _seq INTEGER;
  _p RECORD;
  _revid INTEGER;
  
BEGIN

  IF (NOT fetchMetricBool('RevControl')) THEN -- Deal with BOM if Rev Control Turned off
    SELECT bomhead_id INTO _seq
    FROM bomhead 
    WHERE (bomhead_item_id=pItemid);

    IF (NOT FOUND) THEN  -- No bomhead exists
      _seq := NEXTVAL('bomhead_bomhead_id_seq');
      
      INSERT INTO bomhead 
        (bomhead_id,bomhead_item_id,bomhead_docnum,bomhead_revision,
        bomhead_revisiondate,bomhead_batchsize,bomhead_requiredqtyper,bomhead_rev_id)
        VALUES 
        (_seq,pItemid, pDocumentNumber, pRevision, pRevisionDate, pBatchSize, pRequiredQtyPer,-1);   
    ELSE
      UPDATE bomhead SET
        bomhead_revision	= pRevision,
        bomhead_revisiondate	= pRevisionDate,
        bomhead_docnum		= pDocumentNumber,
        bomhead_batchsize	= pBatchSize,
        bomhead_requiredqtyper = pRequiredQtyPer
      WHERE (bomhead_id=_seq);
    END IF;
    
    RETURN _seq;
  ELSE  -- Deal with Revision Control
    IF (COALESCE(pRevision,'') = '' AND getActiveRevId('BOM',pItemid) != -1) THEN 
        RAISE EXCEPTION 'Revision Control records exist for item.  You must provide a new or existing revision number.';
    END IF;
    
    SELECT * INTO _p
    FROM bomhead
      LEFT OUTER JOIN rev ON (bomhead_rev_id=rev_id),
      item
    WHERE ((bomhead_item_id=pItemid)
    AND (COALESCE(bomhead_revision,'')=COALESCE(pRevision,''))
    AND (bomhead_item_id=item_id));

    IF (NOT FOUND) THEN  -- This is a new bomhead record
      IF LENGTH(pRevision) > 0 THEN  -- We need to create a revision record   
        SELECT createbomrev(pItemid, pRevision) INTO _revid;
        
        UPDATE bomhead SET
          bomhead_revisiondate		= pRevisiondate,
          bomhead_docnum		= pDocumentNumber,
          bomhead_batchsize		= pBatchsize,
          bomhead_requiredqtyper	= pRequiredqtyper
        WHERE (bomhead_rev_id=_revid);
        
        SELECT bomhead_id INTO _seq
        FROM bomhead
        WHERE (bomhead_rev_id=_revid);
        
        RETURN _seq;      
      ELSE  -- Just create a regular bom header record
       _seq := NEXTVAL('bomhead_bomhead_id_seq');
       
       INSERT INTO bomhead 
        (bomhead_id,bomhead_item_id,bomhead_docnum,bomhead_revision,
        bomhead_revisiondate,bomhead_batchsize,bomhead_requiredqtyper,bomhead_rev_id)
        VALUES 
        (_seq,pItemid, pDocumentNumber, pRevision, pRevisionDate, pBatchSize, pRequiredQtyPer,-1);
        
        RETURN _seq;      
        
      END IF;
    ELSE  -- We need to update a record
      IF (_p.rev_status = 'I') THEN
        RAISE EXCEPTION 'Revision % for % is inactive.  Update not allowed.', _p.rev_number, _p.item_number;

      ELSIF (COALESCE(pRevision,'') = COALESCE(_p.bomhead_revision,'')) THEN  -- No change, just update
        UPDATE bomhead SET
          bomhead_revisiondate		= pRevisiondate,
          bomhead_docnum		= pDocumentNumber,
          bomhead_batchsize		= pBatchSize,
          bomhead_requiredqtyper	= pRequiredqtyper
        WHERE (bomhead_id=_p.bomhead_id);

        RETURN _p.bomhead_id;
        
      ELSE -- Need a new revision
        SELECT createbomrev(pItemid, pRevision) INTO _revid;
        
        UPDATE bomhead SET
          bomhead_revisiondate		= pRevisiondate,
          bomhead_docnum		= pDocumentNumber,
          bomhead_batchsize		= pBatchSize,
          bomhead_requiredqtyper	= pRequiredqtyper
        WHERE (bomhead_rev_id=_revid);

        SELECT bomhead_id INTO _seq
        FROM bomhead
        WHERE (bomhead_rev_id=_revid);
        
        RETURN _seq;
      END IF;
    END IF;
  END IF;

  RETURN _seq;

END;

Function: public.savecntct(pflag integer, ptitle text, pnotes integer, pwebaddr integer, pemail text, pfax text, pphone2 text, pphone text, pactive text, pinitials text, psuffix boolean, plastname text, pmiddlename text, pfirstname text, phonorific text, paddrid text, pcrmacctid text, pcontactnumber text, pcntctid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;

BEGIN
  
  SELECT saveCntct( pCntctId, pContactNumber, pCrmAcctId, pAddrId, pHonorific, pFirstName, pMiddleName, pLastName, pSuffix, pInitials, 
	pActive, pPhone, pPhone2, pFax, pEmail, pWebAddr, pNotes, pTitle, pFlag, NULL) INTO _returnVal;
  RETURN _returnVal;

END;

Function: public.savecntct(pflag integer, ptitle text, pwebaddr integer, pemail text, pfax text, pphone2 text, pphone text, psuffix text, plastname text, pmiddlename text, pfirstname text, phonorific text, paddrid text, pcontactnumber text, pcntctid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _returnVal INTEGER;

BEGIN
  
  SELECT saveCntct(pCntctId,pContactNumber,NULL,pAddrId,pHonorific,pFirstName,pMiddleName,pLastName,pSuffix,NULL,
        NULL,pPhone,pPhone2,pFax,pEmail,pWebAddr,NULL,pTitle,pFlag, NULL) INTO _returnVal;
  
  RETURN _returnVal;

END;

Function: public.savecntct(pownerusername integer, pflag text, ptitle integer, pnotes integer, pwebaddr text, pemail text, pfax text, pphone2 text, pphone text, pactive text, pinitials boolean, psuffix text, plastname text, pmiddlename text, pfirstname text, phonorific text, paddrid text, pcrmacctid text, pcontactnumber text, pcntctid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _cntctId INTEGER;
  _cntctNumber TEXT;
  _isNew BOOLEAN;
  _flag TEXT;
  _contactCount INTEGER := 0;

BEGIN
  --Validate
  IF ((pFlag IS NULL) OR (pFlag = '') OR (pFlag = 'CHECK') OR (pFlag = 'CHANGEONE') OR (pFlag = 'CHANGEALL')) THEN
    IF (pFlag='') THEN
      _flag := 'CHECK';
    ELSE
      _flag := COALESCE(pFlag,'CHECK');
    END IF;
  ELSE
	RAISE EXCEPTION 'Invalid Flag (%). Valid flags are CHECK, CHANGEONE or CHANGEALL', pFlag;
  END IF;
  
  --If there is nothing here get out
  IF ( (pCntctId IS NULL OR pCntctId = -1)
	AND (pAddrId IS NULL)
	AND (COALESCE(pFirstName, '') = '')
	AND (COALESCE(pMiddleName, '') = '')
	AND (COALESCE(pLastName, '') = '')
	AND (COALESCE(pSuffix, '') = '')
	AND (COALESCE(pHonorific, '') = '')
	AND (COALESCE(pInitials, '') = '')
	AND (COALESCE(pPhone, '') = '')
	AND (COALESCE(pPhone2, '') = '')
	AND (COALESCE(pFax, '') = '')
	AND (COALESCE(pEmail, '') = '')
	AND (COALESCE(pWebAddr, '') = '')
	AND (COALESCE(pNotes, '') = '')
	AND (COALESCE(pTitle, '') = '') ) THEN
	
	RETURN NULL;

  END IF;
  
  IF (pCntctId IS NULL OR pCntctId = -1) THEN 
    _isNew := true;
    _cntctId := nextval('cntct_cntct_id_seq');
    _cntctNumber := COALESCE(pContactNumber,fetchNextNumber('ContactNumber'));
  ELSE
    SELECT COUNT(cntct_id) INTO _contactCount
      FROM cntct
      WHERE ((cntct_id=pCntctId)
      AND (cntct_first_name=pFirstName)
      AND (cntct_last_name=pLastName));

    -- ask whether new or update if name changes
    -- but only if this isn't a new record with a pre-allocated id
    IF (_contactCount < 1 AND _flag = 'CHECK') THEN
      IF (EXISTS(SELECT cntct_id
                 FROM cntct
                 WHERE (cntct_id=pCntctId))) THEN
        RETURN -10;
      ELSE
        _isNew := true;
        _cntctNumber := fetchNextNumber('ContactNumber');
      END IF;
    ELSIF (_flag = 'CHANGEONE') THEN
      _isNew := true;
      _cntctId := nextval('cntct_cntct_id_seq');
      _cntctNumber := fetchNextNumber('ContactNumber');
    ELSIF (_flag = 'CHANGEALL') THEN
      _isNew := false;
    END IF;
  END IF;

  IF (pContactNumber = '') THEN
    _cntctNumber := fetchNextNumber('ContactNumber');
  ELSE
    _cntctNumber := COALESCE(_cntctNumber,pContactNumber,fetchNextNumber('ContactNumber'));
  END IF;

  IF (_isNew) THEN
    _cntctId := COALESCE(_cntctId,pCntctId,nextval('cntct_cntct_id_seq'));
 
    INSERT INTO cntct (
      cntct_id,cntct_number,
      cntct_crmacct_id,cntct_addr_id,cntct_first_name,
      cntct_last_name,cntct_honorific,cntct_initials,
      cntct_active,cntct_phone,cntct_phone2,
      cntct_fax,cntct_email,cntct_webaddr,
      cntct_notes,cntct_title,cntct_middle,cntct_suffix, cntct_owner_username ) 
    VALUES (
      _cntctId, COALESCE(_cntctNumber,fetchNextNumber('ContactNumber')) ,pCrmAcctId,pAddrId,
      pFirstName,pLastName,pHonorific,
      pInitials,COALESCE(pActive,true),pPhone,pPhone2,pFax,
      pEmail,pWebAddr,pNotes,pTitle,pMiddleName,pSuffix,pOwnerUsername );

    RETURN _cntctId;

  ELSE
    UPDATE cntct SET
      cntct_number=COALESCE(_cntctNumber,fetchNextNumber('ContactNumber')),
      cntct_crmacct_id=COALESCE(pCrmAcctId,cntct_crmacct_id),
      cntct_addr_id=COALESCE(pAddrId,cntct_addr_id),
      cntct_first_name=COALESCE(pFirstName,cntct_first_name),
      cntct_last_name=COALESCE(pLastName,cntct_last_name),
      cntct_honorific=COALESCE(pHonorific,cntct_honorific),
      cntct_initials=COALESCE(pInitials,cntct_initials),
      cntct_active=COALESCE(pActive,cntct_active),
      cntct_phone=COALESCE(pPhone,cntct_phone),
      cntct_phone2=COALESCE(pPhone2,cntct_phone2),
      cntct_fax=COALESCE(pFax,cntct_fax),
      cntct_email=COALESCE(pEmail,cntct_email),
      cntct_webaddr=COALESCE(pWebAddr,cntct_webaddr),
      cntct_notes=COALESCE(pNotes,cntct_notes),
      cntct_title=COALESCE(pTitle,cntct_title),
      cntct_middle=COALESCE(pMiddleName,cntct_middle),
      cntct_suffix=COALESCE(pSuffix,cntct_suffix),
      cntct_owner_username=COALESCE(pOwnerUsername, cntct_owner_username) 
    WHERE (cntct_id=pCntctId);
    
    RETURN pCntctId;

  END IF;
END;

Function: public.saveimageass(text, integer, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSource 	ALIAS FOR $1;
  pSourceId 	ALIAS FOR $2;
  pPurpose 	ALIAS FOR $3;
  pImageid 	ALIAS FOR $4;
  _imageassId INTEGER = 0;

BEGIN

--  See if this link already exists
  SELECT imageass_id INTO _imageassId
  FROM imageass
  WHERE ((imageass_source_id=pSourceId)
  AND (imageass_source=pSource)
  AND (imageass_image_id=pImageId)
  AND (imageass_purpose=pPurpose));

  IF (FOUND) THEN
    RETURN _imageassId;
  END IF;
  
-- See if a record with this purpose already exists (item only)
  IF (pSource = 'I' AND pPurpose != 'M') THEN
    SELECT imageass_id INTO _imageassId
    FROM imageass
    WHERE ((imageass_source_id=pSourceId)
    AND (imageass_source=pSource)
    AND (imageass_purpose=pPurpose));
  END IF;

  IF (_imageassId > 0) THEN
    UPDATE imageass SET
      imageass_image_id=pImageId
    WHERE (imageass_id=_imageassId);
  ELSE
    _imageassId := NEXTVAL('imageass_imageass_id_seq');
    INSERT INTO imageass VALUES (_imageassId,pSourceId,pSource,pImageid,CASE WHEN pSource='I' THEN pPurpose ELSE 'M' END);
  END IF;
  
  RETURN _imageassId;
END;

Function: public.saveipsitem(integer, integer, integer, numeric, numeric, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIpsItemId	ALIAS FOR $1;
  pIpsHeadId	ALIAS FOR $2;
  pItemId	ALIAS FOR $3;
  pQtyBreak	ALIAS FOR $4;
  pPrice	ALIAS FOR $5;
  pQtyUomId	ALIAS FOR $6;
  pPriceUomId	ALIAS FOR $7;
  _ipsitemid	INTEGER;
  _new		BOOLEAN;
BEGIN

  -- Validation
  IF (SELECT COUNT(item_id)=0 FROM item WHERE (item_id=pItemId)) THEN
    RAISE EXCEPTION 'You must provide a valid Item';
  ELSIF (COALESCE(pQtyBreak,0) < 0) THEN
    RAISE EXCEPTION 'Quantity can not be a negative value';
  ELSIF (COALESCE(pPrice,0) < 0) THEN
    RAISE EXCEPTION 'Price must be a negative value';
  ELSIF ((pQtyUomId IS NOT NULL) AND (SELECT COUNT(item_id)=0 FROM
        (SELECT item_id
         FROM item
         WHERE ((item_id=pItemId)
           AND (item_inv_uom_id=pQtyUomId))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_from_uom_id=pQtyUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_to_uom_id=pQtyUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))) AS data)) THEN
    RAISE EXCEPTION 'Qty UOM Must be a valid Selling UOM for the Item';
  ELSIF ((pPriceUomId IS NOT NULL) AND (SELECT COUNT(item_id)=0 FROM
        (SELECT item_id
         FROM item
         WHERE ((item_id=pItemId)
           AND (item_inv_uom_id=pPriceUomId))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_from_uom_id=pPriceUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_to_uom_id=pPriceUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))) AS data)) THEN
    RAISE EXCEPTION 'Price UOM Must be a valid Selling UOM for the Item';
  END IF;

  _new := TRUE;

  IF (pIpsItemId IS NOT NULL) THEN
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsitem
    WHERE (ipsitem_id=pIpsItemId);

    IF (FOUND) THEN
      _new := FALSE;
    ELSE
      RAISE EXCEPTION 'Pricing Schedule Item not found.';
    END IF;
  ELSE
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsitem
    WHERE ((ipsitem_ipshead_id	= pIpsheadId)
      AND (ipsitem_item_id 	= pItemId)
      AND (ipsitem_qtybreak 	= pQtyBreak)
      AND (ipsitem_qty_uom_id = COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))) 
      AND (ipsitem_price_uom_id =
           CASE
             WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
               COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
             ELSE
               COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
           END));
  END IF;
  
  IF (FOUND) THEN
    _new := false;
  ELSE
    _ipsitemid := nextval('ipsitem_ipsitem_id_seq');
  END IF;
  
  IF (_new) THEN
    INSERT INTO ipsitem (
      ipsitem_id,
      ipsitem_ipshead_id, 
      ipsitem_item_id, 
      ipsitem_qtybreak, 
      ipsitem_price, 
      ipsitem_qty_uom_id, 
      ipsitem_price_uom_id,
      ipsitem_discntprcnt,
      ipsitem_fixedamtdiscount) 
    VALUES (
      _ipsitemid,
      pIpsheadId,
      pItemId,
      pQtyBreak, 
      pPrice,
      COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)), 
      CASE
        WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
          COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
        ELSE
          COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
      END,
      0.0,
      0.0);
  ELSE 
    UPDATE ipsitem SET 
      ipsitem_qtybreak = pQtyBreak, 
      ipsitem_price = pPrice, 
      ipsitem_qty_uom_id = COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)), 
      ipsitem_price_uom_id =
      CASE
        WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
          COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
        ELSE
          COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
      END
    WHERE (ipsitem_id=_ipsitemid);
   END IF;

   RETURN _ipsitemid;

END;

Function: public.saveipsitem(ptype integer, pfixedamt integer, ppercent integer, ppriceuomid numeric, pqtyuomid numeric, pprice integer, pqtybreak integer, pitemid numeric, pipsheadid numeric, pipsitemid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _ipsitemid	INTEGER;
  _new		BOOLEAN;
BEGIN

  -- Validation
  IF (SELECT COUNT(item_id)=0 FROM item WHERE (item_id=pItemId)) THEN
    RAISE EXCEPTION 'You must provide a valid Item';
  ELSIF (COALESCE(pQtyBreak,0) < 0) THEN
    RAISE EXCEPTION 'Quantity can not be a negative value';
  ELSIF (COALESCE(pPrice,0) < 0) THEN
    RAISE EXCEPTION 'Price must be a negative value';
  ELSIF ((pQtyUomId IS NOT NULL) AND (SELECT COUNT(item_id)=0 FROM
        (SELECT item_id
         FROM item
         WHERE ((item_id=pItemId)
           AND (item_inv_uom_id=pQtyUomId))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_from_uom_id=pQtyUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_to_uom_id=pQtyUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))) AS data)) THEN
    RAISE EXCEPTION 'Qty UOM Must be a valid Selling UOM for the Item';
  ELSIF ((pPriceUomId IS NOT NULL) AND (SELECT COUNT(item_id)=0 FROM
        (SELECT item_id
         FROM item
         WHERE ((item_id=pItemId)
           AND (item_inv_uom_id=pPriceUomId))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_from_uom_id=pPriceUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))
         UNION
         SELECT item_id
         FROM item,itemuomconv,itemuom,uomtype
         WHERE ((item_id=pItemId)
           AND (itemuomconv_item_id=item_id)
           AND (itemuomconv_to_uom_id=pPriceUomId)
           AND (itemuom_itemuomconv_id=itemuomconv_id)
           AND (itemuom_uomtype_id=uomtype_id)
           AND (uomtype_name='Selling'))) AS data)) THEN
    RAISE EXCEPTION 'Price UOM Must be a valid Selling UOM for the Item';
  END IF;

  _new := TRUE;

  IF (pIpsItemId IS NOT NULL) THEN
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsiteminfo
    WHERE (ipsitem_id=pIpsItemId);

    IF (FOUND) THEN
      _new := FALSE;
    ELSE
      RAISE EXCEPTION 'Pricing Schedule Item not found.';
    END IF;
  ELSE
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsiteminfo
    WHERE ((ipsitem_ipshead_id	= pIpsheadId)
      AND (ipsitem_item_id 	= pItemId)
      AND (ipsitem_qtybreak 	= pQtyBreak)
      AND (ipsitem_qty_uom_id = COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))) 
      AND (ipsitem_price_uom_id =
           CASE
             WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
               COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
             ELSE
               COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
           END));
  END IF;
  
  IF (FOUND) THEN
    _new := false;
  END IF;
  
  IF (_new) THEN
    INSERT INTO ipsiteminfo (
      ipsitem_ipshead_id, 
      ipsitem_item_id, 
      ipsitem_qtybreak, 
      ipsitem_price, 
      ipsitem_qty_uom_id, 
      ipsitem_price_uom_id,
      ipsitem_discntprcnt,
      ipsitem_fixedamtdiscount,
      ipsitem_type) 
    VALUES (
      pIpsheadId,
      pItemId,
      pQtyBreak, 
      pPrice,
      COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)), 
      CASE
        WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
          COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
        ELSE
          COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
      END,
      pPercent,
      pFixedAmt,
      pType)
    RETURNING ipsitem_id INTO _ipsitemid;
  ELSE 
    UPDATE ipsiteminfo SET 
      ipsitem_qtybreak = pQtyBreak, 
      ipsitem_price = pPrice, 
      ipsitem_qty_uom_id = COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)), 
      ipsitem_price_uom_id =
      CASE
        WHEN (pQtyUomId = (SELECT item_inv_uom_id FROM item WHERE item_id = pItemId)) THEN
          COALESCE(pPriceUomId,pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
        ELSE
          COALESCE(pQtyUomId,(SELECT item_inv_uom_id FROM item WHERE item_id = pItemId))
      END,
      ipsitem_discntprcnt=pPercent,
      ipsitem_fixedamtdiscount=pFixedAmt,
      ipsitem_type=pType
    WHERE (ipsitem_id=_ipsitemid);
   END IF;

   RETURN _ipsitemid;

END;

Function: public.saveipsprodcat(integer, integer, integer, numeric, numeric)

Returns: integer

Language: PLPGSQL

DECLARE
  pIpsProdcatId	ALIAS FOR $1;
  pIpsHeadId	ALIAS FOR $2;
  pProdCatId	ALIAS FOR $3;
  pQtyBreak	ALIAS FOR $4;
  pDiscount	ALIAS FOR $5;
  _ipsprodcatid	INTEGER;
  _new		BOOLEAN;
  
BEGIN

  -- Validation
  IF (SELECT COUNT(*)=0 FROM prodcat WHERE (prodcat_id=pProdcatId)) THEN
    RAISE EXCEPTION 'You must provide a valid Product Category';
  ELSIF (COALESCE(pQtyBreak,0) < 0) THEN
    RAISE EXCEPTION 'Quantity can not be a negative value';
  ELSIF (COALESCE(pDiscount,0) < 0) THEN
    RAISE EXCEPTION 'Discount must be a negative value';
  END IF;
    
  _new := TRUE;

  IF (pIpsProdcatId IS NOT NULL) THEN
    SELECT ipsprodcat_id INTO _ipsprodcatid
    FROM ipsprodcat
    WHERE (ipsprodcat_id=pIpsprodcatId);

    IF (FOUND) THEN
      _new := FALSE;
    ELSE
      RAISE EXCEPTION 'Pricing Schedule Product Category not found';
    END IF;
  ELSE
    SELECT ipsprodcat_id INTO _ipsprodcatid
    FROM ipsprodcat
    WHERE ((ipsprodcat_ipshead_id=pIpsheadId)
      AND (ipsprodcat_prodcat_id=pProdcatId)
      AND (ipsprodcat_qtybreak=pQtyBreak));

    IF (FOUND) THEN
      _new := false;
    ELSE
      _ipsprodcatid := nextval('ipsprodcat_ipsprodcat_id_seq');
    END IF;
  END IF;
  
  IF (_new) THEN
    INSERT INTO ipsprodcat (
      ipsprodcat_id,
      ipsprodcat_ipshead_id, 
      ipsprodcat_prodcat_id, 
      ipsprodcat_qtybreak, 
      ipsprodcat_discntprcnt) 
    VALUES (
      _ipsprodcatid,
      pIpsheadId,
      pProdcatId,
      pQtyBreak, 
      pDiscount * .01);
  ELSE 
    UPDATE ipsprodcat SET 
      ipsprodcat_qtybreak = pQtyBreak, 
      ipsprodcat_discntprcnt = pDiscount * .01
    WHERE (ipsprodcat_id=_ipsprodcatid);
  END IF;

  RETURN _ipsprodcatid;
END;

Function: public.saveipsprodcat(integer, integer, integer, numeric, numeric, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIpsProdcatId	    ALIAS FOR $1;
  pIpsHeadId	    ALIAS FOR $2;
  pProdCatId	    ALIAS FOR $3;
  pQtyBreak	    ALIAS FOR $4;
  pDiscount	    ALIAS FOR $5;
  pFixedAmtDiscount ALIAS FOR $6;
  _ipsprodcatid	INTEGER;
  _new		BOOLEAN;
  
BEGIN

  -- Validation
  IF (SELECT COUNT(*)=0 FROM prodcat WHERE (prodcat_id=pProdcatId)) THEN
    RAISE EXCEPTION 'You must provide a valid Product Category';
  ELSIF (COALESCE(pQtyBreak,0) < 0) THEN
    RAISE EXCEPTION 'Quantity can not be a negative value';
  ELSIF (COALESCE(pDiscount,0) < 0) THEN
    RAISE EXCEPTION 'Discount must be a negative value';
  END IF;
    
  _new := TRUE;

  IF (pIpsProdcatId IS NOT NULL) THEN
    SELECT ipsprodcat_id INTO _ipsprodcatid
    FROM ipsprodcat
    WHERE (ipsprodcat_id=pIpsprodcatId);

    IF (FOUND) THEN
      _new := FALSE;
    ELSE
      RAISE EXCEPTION 'Pricing Schedule Product Category not found';
    END IF;
  ELSE
    SELECT ipsprodcat_id INTO _ipsprodcatid
    FROM ipsprodcat
    WHERE ((ipsprodcat_ipshead_id=pIpsheadId)
      AND (ipsprodcat_prodcat_id=pProdcatId)
      AND (ipsprodcat_qtybreak=pQtyBreak));

    IF (FOUND) THEN
      _new := false;
    ELSE
      _ipsprodcatid := nextval('ipsprodcat_ipsprodcat_id_seq');
    END IF;
  END IF;
  
  IF (_new) THEN
    INSERT INTO ipsprodcat (
      ipsprodcat_id,
      ipsprodcat_ipshead_id, 
      ipsprodcat_prodcat_id, 
      ipsprodcat_qtybreak, 
      ipsprodcat_discntprcnt,
      ipsprodcat_fixedamtdiscount)  
    VALUES (
      _ipsprodcatid,
      pIpsheadId,
      pProdcatId,
      pQtyBreak, 
      pDiscount * .01,
      pFixedAmtDiscount);
  ELSE 
    UPDATE ipsprodcat SET 
      ipsprodcat_qtybreak = pQtyBreak, 
      ipsprodcat_discntprcnt = pDiscount * .01,
      ipsprodcat_fixedamtdiscount = pFixedAmtDiscount 
    WHERE (ipsprodcat_id=_ipsprodcatid);
  END IF;

  RETURN _ipsprodcatid;
END;

Function: public.saveipsprodcat(ptype integer, pfixedamtdiscount integer, pdiscount integer, pqtybreak numeric, pprodcatid numeric, pipsheadid numeric, pipsprodcatid text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _ipsitemid	INTEGER;
  _new		BOOLEAN;
  
BEGIN

  -- Validation
  IF (SELECT COUNT(*)=0 FROM prodcat WHERE (prodcat_id=pProdcatId)) THEN
    RAISE EXCEPTION 'You must provide a valid Product Category';
  ELSIF (COALESCE(pQtyBreak,0) < 0) THEN
    RAISE EXCEPTION 'Quantity can not be a negative value';
  ELSIF (COALESCE(pDiscount,0) < 0) THEN
    RAISE EXCEPTION 'Discount must be a negative value';
  END IF;
    
  _new := TRUE;

  IF (pIpsProdcatId IS NOT NULL) THEN
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsiteminfo
    WHERE (ipsprodcat_id=pIpsprodcatId);

    IF (FOUND) THEN
      _new := FALSE;
    ELSE
      RAISE EXCEPTION 'Pricing Schedule Product Category not found';
    END IF;
  ELSE
    SELECT ipsitem_id INTO _ipsitemid
    FROM ipsiteminfo
    WHERE ((ipsitem_ipshead_id=pIpsheadId)
      AND (ipsitem_prodcat_id=pProdcatId)
      AND (ipsitem_qtybreak=pQtyBreak));

    IF (FOUND) THEN
      _new := false;
    ELSE
      _ipsitemid := nextval('ipsitem_ipsitem_id_seq');
    END IF;
  END IF;
  
  IF (_new) THEN
    INSERT INTO ipsiteminfo (
      ipsitem_id,
      ipsitem_ipshead_id, 
      ipsitem_prodcat_id, 
      ipsitem_qtybreak,
      ipsitem_price, 
      ipsitem_discntprcnt,
      ipsitem_fixedamtdiscount,
      ipsitem_type)  
    VALUES (
      _ipsitemid,
      pIpsheadId,
      pProdcatId,
      pQtyBreak, 
      0.0,
      pDiscount * .01,
      pFixedAmtDiscount,
      pType);
  ELSE 
    UPDATE ipsiteminfo SET 
      ipsitem_qtybreak = pQtyBreak, 
      ipsitem_discntprcnt = pDiscount * .01,
      ipsitem_fixedamtdiscount = pFixedAmtDiscount,
      ipsitem_type = pType 
    WHERE (ipsitem_id=_ipsitemid);
  END IF;

  RETURN _ipsitemid;
END;

Function: public.saveitemimage(integer, bpchar, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pPurpose ALIAS FOR $2;
  pImageid ALIAS FOR $3;
  _itemimageId INTEGER;

BEGIN
-- See if a record with this purpose already exists
  SELECT imageass_id INTO _itemimageId
  FROM imageass
  WHERE ( (imageass_source='I')
    AND   (imageass_source_id=pItemid)
    AND   (imageass_purpose=pPurpose) );

  IF (FOUND) THEN
    UPDATE imageass SET imageass_image_id=pImageId
    WHERE (imageass_id=_itemimageId);
  ELSE
    _itemimageId := NEXTVAL('imageass_imageass_id_seq');
    INSERT INTO imageass VALUES (_itemimageId,pItemid,'I',pImageid,pPurpose);
  END IF;
  
  RETURN _itemimageId;
END;

Function: public.saveitemuomconv(integer, integer, numeric, integer, numeric, boolean, integer[])

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemId ALIAS FOR $1;
  pFromUomId ALIAS FOR $2;
  pFromValue ALIAS FOR $3;
  pToUomId ALIAS FOR $4;
  pToValue ALIAS FOR $5;
  pFractional ALIAS FOR $6;
  pUomTypes ALIAS FOR $7;
  _p RECORD;
  _fromUomId INTEGER;
  _fromValue NUMERIC;
  _toUomId INTEGER;
  _toValue NUMERIC;
  _fractional BOOLEAN;
  _seq INTEGER;
  _i INTEGER;
  _uomtype TEXT;

BEGIN
-- Make sure we have some itemtypes
  IF (pUomTypes IS NULL) OR (ARRAY_UPPER(pUomTypes,1) = 0) THEN
	RAISE EXCEPTION 'You must include at least one item type.';
  END IF;

-- If this is a global UOM, over-ride with global data.
  SELECT * INTO _p
  FROM uomconv
  WHERE ((((uomconv_from_uom_id=pFromUomId)
  AND (uomconv_to_uom_id=pToUomId))
  OR ((uomconv_from_uom_id=pToUomId)
  AND (uomconv_to_uom_id=pFromUomId))));

  IF (FOUND) THEN
    _fromUomId := _p.uomconv_from_uom_id;
    _toUomId := _p.uomconv_to_uom_id;
    _fromValue := _p.uomconv_from_value;
    _toValue := _p.uomconv_to_value;
    _fractional := _p.uomconv_fractional;
    RAISE NOTICE 'Defaulted to global Unit of Measure conversion ratios.';
  ELSE
    _fromUomId := pFromUomId;
    _fromValue := pFromValue;
    _toUomId := pToUomId;
    _toValue := pToValue;
    _fractional := pFractional;
  END IF;

-- See if an item conversion exists going the other way
  SELECT f.uom_name AS f_uom, t.uom_name as t_uom INTO _p
  FROM itemuomconv,uom f, uom t
  WHERE ((itemuomconv_item_id=pItemId)
  AND (itemuomconv_from_uom_id=_toUomId)
  AND (itemuomconv_to_uom_id=_fromUomId)
  AND (f.uom_id=itemuomconv_from_uom_id)
  AND (t.uom_id=itemuomconv_to_uom_id));
  IF (FOUND) THEN
    RAISE EXCEPTION 'Unit of measure conversion already exists going from % to %.',_p.f_uom,_p.t_uom;
  END IF;

-- See if an item conversion record exists
  SELECT * INTO _p
  FROM itemuomconv
  WHERE ((itemuomconv_item_id=pItemId)
  AND (itemuomconv_from_uom_id=_fromUomId)
  AND (itemuomconv_to_uom_id=_toUomId));

-- Update if found
  IF (FOUND) THEN
    UPDATE itemuomconv SET
      itemuomconv_from_value=_fromValue,
      itemuomconv_to_value=_toValue,
      itemuomconv_fractional=_fractional
    WHERE (itemuomconv_id=_p.itemuomconv_id);
    _seq := _p.itemuomconv_id;
    
    --Delete old type list
    DELETE FROM itemuom WHERE itemuom_itemuomconv_id=_p.itemuomconv_id;
  ELSE
  
-- Otherwise create a new one
    SELECT NEXTVAL('itemuomconv_itemuomconv_id_seq') INTO _seq;
    INSERT INTO itemuomconv VALUES
      (_seq, pItemId,_fromUomId,_fromValue,_toUomId,_toValue,_fractional);
  END IF;
  
-- Build new type list
  FOR _i IN 1..ARRAY_UPPER(pUomTypes,1)
  LOOP
    SELECT uomtype_name INTO _uomtype
    FROM itemuomconv, itemuom, uomtype
    WHERE ((itemuom_uomtype_id=uomtype_id)
    AND (itemuomconv_id=itemuom_itemuomconv_id)
    AND (itemuomconv_item_id=pItemId)
    AND (uomtype_name != 'Selling')
    AND (itemuom_uomtype_id=pUomTypes[_i]));
    IF (FOUND) THEN
      RAISE EXCEPTION 'Unit of Measure Type % is already used on this item',_uomtype;
    ELSE
      INSERT INTO itemuom (itemuom_itemuomconv_id,itemuom_uomtype_id)
      VALUES (_seq,pUomTypes[_i]);
    END IF;
  END LOOP;
  
  RETURN _seq;
END;

Function: public.savemetasql(text, text, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN saveMetasql($1, $2, $3, $4, true, NULL, 0);
END;

Function: public.savemetasql(text, text, text, text, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN saveMetasql($1, $2, $3, $4, $5, NULL, 0);
END;

Function: public.savemetasql(text, text, text, text, boolean, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN saveMetasql($1, $2, $3, $4, $5, $6, 0);
END;

Function: public.savemetasql(text, text, text, text, boolean, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pGroup	ALIAS FOR $1;
  pName 	ALIAS FOR $2;
  pNotes	ALIAS FOR $3;
  pQuery	ALIAS FOR $4;
  pSystem       ALIAS FOR $5;
  pSchema       ALIAS FOR $6;
  pGrade        ALIAS FOR $7;
  _metasqlid	INTEGER;
  _debug        BOOL    := false;
  _grade        INTEGER;
  _insertstr    TEXT;
  _table        TEXT;
  
BEGIN

  --See if Query already exists
  SELECT metasql_id INTO _metasqlid
  FROM metasql
  WHERE ((metasql_group=pGroup)
     AND (metasql_name=pName)
     AND (metasql_grade=pGrade));

  IF (FOUND) THEN
    IF (_debug) THEN RAISE NOTICE 'update metasql'; END IF;
    UPDATE metasql SET
      metasql_group=pGroup,
      metasql_name=pName,
      metasql_notes=pNotes,
      metasql_query=pQuery
    WHERE (metasql_id=_metasqlid);
  ELSE
    IF (COALESCE(pSchema, 'public') = 'public' OR
        TRIM(pSchema) = '') THEN
      _table := 'metasql';
    ELSE
      _table := pSchema || '.pkgmetasql';
    END IF;

    IF (pGrade IS NULL) THEN
      SELECT MAX(metasql_grade) + 1 INTO _grade
      FROM metasql
      WHERE ((metasql_group=pGroup)
         AND (metasql_name=pName));
    ELSE
      _grade := pGrade;
    END IF;

    _insertstr := 'INSERT INTO ' || _table ||
                  ' (metasql_group, metasql_name, metasql_notes, ' ||
                  '  metasql_query, metasql_grade) VALUES (' ||
                  COALESCE(quote_literal(pGroup),'NULL') || ',' || COALESCE(quote_literal(pName), 'NULL') || ',' ||
                  COALESCE(quote_literal(pNotes), 'NULL') || ',' || COALESCE(quote_literal(pQuery), 'NULL') ||',' ||
                  COALESCE(quote_literal(_grade), 'NULL') || ') RETURNING metasql_id;' ;

    IF (_debug) THEN RAISE NOTICE '%', _insertstr; END IF;
    EXECUTE _insertstr INTO _metasqlid;
  END IF;
 
  RETURN _metasqlid;
END;

Function: public.scraps(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;

BEGIN
  IF (pTransType IN ('SI', 'SM', 'EX')) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.scrapwomaterial(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN scrapWoMaterial($1, $2, CURRENT_TIMESTAMP);
END;

Function: public.scrapwomaterial(integer, numeric, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWomatlid	ALIAS FOR $1;
  pQty		ALIAS FOR $2;
  pGlDistTS     ALIAS FOR $3;
  _costmethod         	CHAR(1);
  _scrapValue		NUMERIC;
  _r                   	RECORD;

BEGIN
  -- Validate
  IF (pQty <= 0) THEN
    RAISE EXCEPTION 'Scrap quantity must be a positive number';
  ELSIF ( ( SELECT (womatl_qtyiss < pQty)
	     FROM womatl
	     WHERE (womatl_id=pWomatlid) ) ) THEN
    RAISE EXCEPTION 'You may not scrap more material than has been issued';
  END IF;

  -- Get the wip G/L account
  SELECT costcat_wip_accnt_id
    INTO _r
    FROM womatl, wo, itemsite, costcat
   WHERE((womatl_wo_id=wo_id)
     AND (wo_itemsite_id=itemsite_id)
     AND (itemsite_costcat_id=costcat_id)
     AND (womatl_id=pWomatlid));

  -- Calculate scrap value
  SELECT itemsite_costmethod INTO _costmethod
  FROM womatl
    JOIN itemsite ON (womatl_itemsite_id=itemsite_id)
  WHERE (womatl_id=pWomatlid);

  IF (_costmethod = 'S') THEN
    SELECT ROUND((stdCost(itemsite_item_id) * itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, pQty)),2)
    INTO _scrapValue
    FROM womatl
      JOIN itemsite ON (womatl_itemsite_id=itemsite_id)
    WHERE (womatl_id=pWomatlid);
     
  ELSIF (_costmethod = 'A') THEN
    SELECT ROUND((SUM(invhist_invqty * invhist_unitcost)-womatl_scrapvalue)/
            (CASE WHEN (SUM(invhist_invqty)-itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtywipscrap) = 0) THEN
              1
            ELSE
              SUM(invhist_invqty)-itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtywipscrap)
            END),2) * itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, pQty)
      INTO _scrapValue
    FROM womatl
        JOIN womatlpost ON (womatl_id=womatlpost_womatl_id)
        JOIN invhist ON (womatlpost_invhist_id=invhist_id)
        JOIN itemsite ON (womatl_itemsite_id=itemsite_id)
    WHERE (womatl_id=pWomatlid)
    GROUP BY itemsite_item_id,womatl_uom_id,womatl_qtywipscrap,womatl_scrapvalue;
  ELSE
    RAISE EXCEPTION 'Cost method not supported to scrap this item';
  END IF;

  --  Distribute to G/L
  PERFORM insertGLTransaction( 'W/O', 'WO', formatWoNumber(womatl_wo_id),
		 ('Scrap ' || item_number || ' from Work Order'),
		 getPrjAccntId(wo_prj_id, _r.costcat_wip_accnt_id), getPrjAccntId(wo_prj_id, costcat_mfgscrap_accnt_id), -1,
		 _scrapValue, date(pGlDistTS) )
  FROM wo, womatl, itemsite, item, costcat
  WHERE ( (wo_id=womatl_wo_id)
   AND (womatl_itemsite_id=itemsite_id)
   AND (itemsite_item_id=item_id)
   AND (itemsite_costcat_id=costcat_id)
   AND (womatl_id=pWomatlid) );

  UPDATE womatl
  SET womatl_qtywipscrap=(womatl_qtywipscrap + pQty),
    womatl_scrapvalue = womatl_scrapvalue + _scrapValue,
    womatl_qtyiss=(womatl_qtyiss - pQty)
  WHERE (womatl_id=pWomatlid);

  UPDATE wo
  SET wo_wipvalue = wo_wipvalue-_scrapValue,
    wo_postedvalue = wo_postedvalue-_scrapValue
  FROM womatl
  WHERE ((womatl_id=pWomatlid)
   AND (wo_id=womatl_wo_id));

  RETURN pWomatlid;

END;

Function: public.selectbalanceforbilling(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoheadid ALIAS FOR $1;
  _returnval	BOOLEAN := TRUE;
  _doSelect BOOLEAN;
  _result INTEGER;
  _soitem RECORD;

BEGIN

  FOR _soitem IN
    -- Get the shipments for this SO.  Kits are not shipped
    SELECT cust_partialship, coitem_id,
           coitem_linenumber, 'NOTK' AS item_type,
           SUM(shipitem_qty) AS qty,
           ( (SUM(shipitem_qty) >= (coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned + SUM(shipitem_qty))) OR
             (NOT cust_partialship) ) AS toclose
    FROM cohead JOIN custinfo ON (cust_id=cohead_cust_id)
                JOIN coitem ON (coitem_cohead_id=cohead_id)
                JOIN shipitem ON ( (shipitem_orderitem_id=coitem_id) AND (NOT shipitem_invoiced) )
                JOIN shiphead ON ( (shiphead_id=shipitem_shiphead_id) AND (shiphead_order_type='SO') AND (shiphead_shipped) )
    WHERE (cohead_id=pSoheadid)
    GROUP BY cust_partialship, coitem_id, item_type,
             coitem_linenumber, coitem_qtyord,
             coitem_qtyshipped, coitem_qtyreturned
    UNION
    -- Get the Kits for this SO
    SELECT cust_partialship, coitem_id,
           coitem_linenumber, 'K' AS item_type,
           coitem_qtyord AS qty,
           TRUE AS toclose
    FROM cohead JOIN custinfo ON (cust_id=cohead_cust_id)
                JOIN coitem ON (coitem_cohead_id=cohead_id AND coitem_status='O')
                JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
                JOIN item ON ( (item_id=itemsite_item_id) AND (item_type='K') )
    WHERE (cohead_id=pSoheadid)
  LOOP

    _doSelect := true;
    IF(_soitem.item_type = 'K') THEN
      -- see if all the sub items are shipped
      SELECT coitem_id
        INTO _result
        FROM coitem
       WHERE((coitem_cohead_id=pSoheadid)
         AND (coitem_linenumber=_soitem.coitem_linenumber)
         AND (coitem_subnumber > 0)
         AND ((coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) > 0))
       LIMIT 1;
      IF( FOUND ) THEN
        _doSelect := false;
      END IF;
    END IF;

    IF (_doSelect) THEN
      -- do as much as we can but still report errors if they occur
      IF (selectForBilling(_soitem.coitem_id, _soitem.qty, _soitem.toclose) < 0) THEN
        _returnval := FALSE;
      END IF;
    END IF;

  END LOOP;

  RETURN _returnval;

END;

Function: public.selectdiscountitemsforpayment(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pBankaccntid ALIAS FOR $2;
  _currid INTEGER;
  _r RECORD;

BEGIN

  SELECT bankaccnt_curr_id INTO _currid
  FROM bankaccnt
  WHERE (bankaccnt_id=pBankaccntid);

  FOR _r IN SELECT apopen_id
              FROM apopen, terms
             WHERE((CURRENT_DATE <= determineDiscountDate(apopen_terms_id, apopen_docdate))
               AND (terms_discprcnt > 0.0)
               AND (apopen_terms_id=terms_id)
               AND (apopen_open)
               AND (apopen_status = 'O')
               AND (apopen_doctype IN ('V', 'D'))
               AND (apopen_vend_id=pVendid)
               AND (apopen_curr_id=_currid) ) LOOP
    PERFORM selectPayment(_r.apopen_id, pBankaccntid);
  END LOOP;

  RETURN 1;

END;

Function: public.selectdueitemsforpayment(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pVendid ALIAS FOR $1;
  pBankaccntid ALIAS FOR $2;
  _currid INTEGER;

BEGIN

  SELECT bankaccnt_curr_id INTO _currid
  FROM bankaccnt
  WHERE (bankaccnt_id=pBankaccntid);

  PERFORM selectPayment(apopen_id, pBankaccntid)
     FROM apopen
    WHERE((apopen_open)
      AND (apopen_vend_id=pVendid)
      AND (apopen_duedate <= CURRENT_DATE)
      AND (apopen_status = 'O')
      AND (apopen_doctype IN ('V', 'D'))
      AND (apopen_curr_id=_currid) );

  RETURN 1;

END;

Function: public.selectforbilling(integer, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemid	ALIAS FOR $1;
  pQty	ALIAS FOR $2;
  pClose	ALIAS FOR $3;
  _itemid	INTEGER := NULL;
  _taxzoneid	INTEGER := NULL;
  _taxid	INTEGER := NULL;
  _taxtypeid	INTEGER := NULL;

BEGIN
  SELECT cobmisc_taxzone_id,  item_id, coitem_taxtype_id
  INTO _taxzoneid,  _itemid, _taxtypeid
  FROM cobmisc, coitem, itemsite, item
  WHERE ((cobmisc_cohead_id = coitem_cohead_id)
  AND   (NOT cobmisc_posted)
  AND   (coitem_itemsite_id = itemsite_id)
  AND   (itemsite_item_id = item_id)
  AND   (coitem_id = pSoitemid) )
  LIMIT 1;

   RETURN selectforbilling(pSoitemid, pQty, pClose, _taxtypeid);
END;

Function: public.selectforbilling(integer, numeric, boolean, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoitemid	ALIAS FOR $1;
  pQty		ALIAS FOR $2;
  pClose	ALIAS FOR $3;
  ptaxtypeid	ALIAS FOR $4;
  _cobillid INTEGER;
  _r RECORD;

BEGIN

-- Get some information
  SELECT cobmisc_id, cobmisc_taxzone_id, coitem_id, coitem_price,
    coitem_price_invuomratio AS invpricerat, coitem_qty_invuomratio, item_id
  INTO _r
  FROM cobmisc, coitem, itemsite, item, site()
  WHERE ((cobmisc_cohead_id = coitem_cohead_id)
  AND   (NOT cobmisc_posted)
  AND   (coitem_itemsite_id = itemsite_id)
  AND   (itemsite_item_id = item_id)
  AND   (coitem_id = pSoitemid)
  AND   (itemsite_warehous_id = warehous_id) )
  LIMIT 1;

-- check to make sure the qty to bill for is not less than
-- the total un-invoiced shipped amount
  IF ((SELECT (pQty < SUM(shipitem_qty))
       FROM shipitem, shiphead, coitem
       WHERE ( (shipitem_shiphead_id=shiphead_id)
       AND (shiphead_order_type='SO')
       AND (shiphead_order_id=coitem_cohead_id)
       AND (shipitem_orderitem_id=coitem_id)
       AND (shiphead_shipped)
       AND (NOT shipitem_invoiced)
       AND (coitem_id=pSoitemid) ) ) ) THEN
    RETURN -1;
  END IF;

  SELECT cobill_id INTO _cobillid
  FROM cobill, cobmisc, coitem
  WHERE ((cobill_cobmisc_id = cobmisc_id)
  AND (cobmisc_cohead_id = coitem_cohead_id)
  AND (cobill_coitem_id = coitem_id)
  AND (NOT cobmisc_posted)
  AND (coitem_id = pSoitemid));

  IF (FOUND) THEN
    UPDATE cobill
    SET cobill_selectdate = CURRENT_DATE,
        cobill_select_username = getEffectiveXtUser(),
        cobill_qty = pQty,
        cobill_toclose = pClose,
	cobill_taxtype_id = ptaxtypeid
    WHERE (cobill_id=_cobillid);

  ELSE
    SELECT NEXTVAL('cobill_cobill_id_seq') INTO _cobillid;
    INSERT INTO cobill
    (cobill_id, cobill_coitem_id, cobill_cobmisc_id,
     cobill_selectdate, cobill_select_username,
     cobill_qty, cobill_toclose,
     cobill_taxtype_id)
    VALUES
    (_cobillid, _r.coitem_id, _r.cobmisc_id,
      CURRENT_DATE, getEffectiveXtUser(),
      pQty, pClose,
      ptaxtypeid);
  END IF;

  RETURN _cobillid;

END;

Function: public.selectpayment(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  pBankaccntid ALIAS FOR $2;
  _p RECORD;
  _apselectid INTEGER;
  _amount NUMERIC;
  _discount NUMERIC;
BEGIN

  SELECT apopen_amount, apopen_paid,
         apopen_doctype, apopen_docdate,
         apopen_curr_id,
         apopen_amount - apopen_paid
           - COALESCE((SELECT SUM(currToCurr(checkitem_curr_id,
                                             apopen_curr_id,
                                             checkitem_amount + checkitem_discount,
                                             checkhead_checkdate))
                         FROM checkitem, checkhead
                        WHERE((checkitem_checkhead_id=checkhead_id)
                          AND (checkitem_apopen_id=apopen_id)
                          AND (NOT checkhead_deleted)
                          AND (NOT checkhead_replaced)
                          AND (NOT checkhead_posted)) ),0) AS balance,
         noNeg(COALESCE(apopen_discountable_amount, 0) *
               CASE WHEN (CURRENT_DATE <= determineDiscountDate(apopen_terms_id, apopen_docdate)) THEN terms_discprcnt
                    ELSE 0.0 END - discount_applied) AS discount_available
    INTO _p
    FROM apopen LEFT OUTER JOIN terms ON (apopen_terms_id=terms_id),
         (SELECT COALESCE(SUM(apapply_amount),0) AS discount_applied
            FROM apapply, apopen
           WHERE((apapply_target_apopen_id=pApopenid)
             AND (apapply_source_apopen_id=apopen_id)
             AND (apopen_discount)) ) AS data
   WHERE(apopen_id=pApopenid);
  IF(NOT FOUND OR (NOT _p.apopen_doctype IN ('V','D'))) THEN
    RETURN -1;
  END IF;

  _discount := round(_p.discount_available, 2);
  _amount := noNeg(round(_p.balance, 2) - _discount);

  IF (round(_p.balance,2) < (_discount + _amount)) THEN
    RETURN -2;
  END IF;

  IF (_amount > 0) THEN
    SELECT apselect_id INTO _apselectid
    FROM apselect
    WHERE (apselect_apopen_id=pApopenid);

    IF (FOUND) THEN
      UPDATE apselect
         SET apselect_amount=_amount,
             apselect_discount=_discount,
             apselect_curr_id = _p.apopen_curr_id
       WHERE(apselect_id=_apselectid);
    ELSE
      SELECT NEXTVAL('apselect_apselect_id_seq') INTO _apselectid;

      INSERT INTO apselect
      ( apselect_id, apselect_apopen_id,
        apselect_amount, apselect_discount,
        apselect_bankaccnt_id,
        apselect_curr_id, apselect_date )
      VALUES
      ( _apselectid, pApopenid,
        _amount, _discount,
        pBankaccntid,
        _p.apopen_curr_id, _p.apopen_docdate );
    END IF;
  ELSE
    _apselectid := 0;
  END IF;
  
  RETURN _apselectid;

END;

Function: public.selectuninvoicedshipment(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipheadid ALIAS FOR $1;
  _cobmiscid INTEGER;
  _coheadid  INTEGER;
  _r RECORD;
  _cobillid INTEGER;

BEGIN

  -- make a cobmisc head if it doesn't already exist for this cohead
  SELECT shiphead_order_id, createBillingHeader(shiphead_order_id)
    INTO _coheadid, _cobmiscid
    FROM shiphead
    JOIN shipitem ON (shipitem_shiphead_id=shiphead_id)
   WHERE (shiphead_shipped
      AND NOT shipitem_invoiced
      AND (shiphead_id=pShipheadid));

  --  Grab all of the uninvoiced shipitem records
  FOR _r IN SELECT cohead_id, coitem_id, SUM(shipitem_qty) AS qty,
                   coitem_price, coitem_price_invuomratio AS invpricerat, coitem_qty_invuomratio, item_id,
                   ( ((coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned) <= 0)
                    OR (NOT cust_partialship) ) AS toclose, coitem_taxtype_id
            FROM shiphead, shipitem, coitem, cohead, custinfo, itemsite, item
            WHERE ( (shipitem_shiphead_id=shiphead_id)
             AND (shipitem_orderitem_id=coitem_id)
             AND (coitem_cohead_id=cohead_id)
             AND (shiphead_shipped)
             AND (NOT shipitem_invoiced)
             AND (coitem_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (cohead_cust_id=cust_id)
             AND (item_type != 'K')
             AND (cohead_id=_coheadid)
             AND (shiphead_id=pShipheadid) )
            GROUP BY cohead_id, coitem_id, cust_partialship, coitem_taxtype_id,
                     coitem_qtyord, coitem_qtyshipped, coitem_qtyreturned,
                     coitem_price, invpricerat, coitem_qty_invuomratio, item_id
            UNION
            SELECT cohead_id, coitem_id, coitem_qtyord AS qty,
                   coitem_price, coitem_price_invuomratio AS invpricerat, coitem_qty_invuomratio, item_id,
                   true AS toclose, coitem_taxtype_id
              FROM shiphead, cohead, custinfo, itemsite, item, coitem AS kit
             WHERE((shiphead_order_id=cohead_id)
               AND (coitem_cohead_id=cohead_id)
               AND (coitem_status='O')
               AND (shiphead_shipped)
               AND (coitem_itemsite_id=itemsite_id)
               AND (itemsite_item_id=item_id)
               AND (cohead_cust_id=cust_id)
               AND (item_type = 'K')
               AND (cohead_id=_coheadid)
               AND (shiphead_id=pShipheadid)
               AND (coitem_linenumber NOT IN
                      (SELECT sub.coitem_linenumber
                       FROM coitem AS sub
                       WHERE sub.coitem_cohead_id=cohead_id     -- cohead for kit
                        AND sub.coitem_linenumber=kit.coitem_linenumber
                        AND sub.coitem_subnumber > 0
                        AND ((sub.coitem_qtyord - sub.coitem_qtyshipped + sub.coitem_qtyreturned) > 0)
                        LIMIT 1)
               ))
             GROUP BY cohead_id, coitem_id, cust_partialship, coitem_taxtype_id,
                      coitem_qtyord, coitem_qtyshipped, coitem_qtyreturned,
                      coitem_price, invpricerat, coitem_qty_invuomratio, item_id, coitem_linenumber
  LOOP

    SELECT cobill_id INTO _cobillid
      FROM cobill, cobmisc, coitem
     WHERE ((cobill_cobmisc_id=cobmisc_id)
       AND  (cobmisc_cohead_id=coitem_cohead_id)
       AND  (cobill_coitem_id=coitem_id)
       AND  (NOT cobmisc_posted)
       AND  (cobill_cobmisc_id=_cobmiscid)
       AND  (coitem_id=_r.coitem_id))
     LIMIT 1;

    IF (FOUND) THEN
      UPDATE cobill
         SET cobill_selectdate = CURRENT_DATE,
             cobill_select_username = getEffectiveXtUser(),
             cobill_qty = cobill_qty + _r.qty,
             cobill_toclose = _r.toclose,
             cobill_taxtype_id = _r.coitem_taxtype_id
      WHERE (cobill_id=_cobillid);
    ELSE
--  Now insert the cobill line
      INSERT INTO cobill
      ( cobill_cobmisc_id, cobill_coitem_id,
        cobill_selectdate, cobill_select_username,
        cobill_qty, cobill_toclose,
        cobill_taxtype_id )
      VALUES
      ( _cobmiscid, _r.coitem_id,
        CURRENT_DATE, getEffectiveXtUser(),
        _r.qty, _r.toclose,
         _r.coitem_taxtype_id );
     END IF;

  END LOOP;

  RETURN _cobmiscid;

END;

Function: public.selectuninvoicedshipments(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  _r RECORD;
  _recordCounter INTEGER := 0;

BEGIN

--  Grab all of the uninvoiced shipitem records
  FOR _r IN SELECT DISTINCT shiphead_id
            FROM shiphead, shipitem, coitem, itemsite
            WHERE ( (shiphead_order_type='SO')
             AND (shipitem_shiphead_id=shiphead_id)
             AND (shipitem_orderitem_id=coitem_id)
             AND (coitem_itemsite_id=itemsite_id)
             AND (coitem_status <> 'C')
             AND ( (pWarehousid = -1) OR (itemsite_warehous_id=pWarehousid) )
             AND (shiphead_shipped)
             AND (NOT shipitem_invoiced)
             AND (coitem_id NOT IN ( SELECT cobill_coitem_id
                                     FROM cobmisc, cobill
                                     WHERE ((cobill_cobmisc_id=cobmisc_id)
                                      AND (NOT cobmisc_posted) ) ) ) ) LOOP

      PERFORM selectUninvoicedShipment(_r.shiphead_id);

    _recordCounter := _recordCounter + 1;

  END LOOP;

  RETURN _recordCounter;

END;

Function: public.selectuninvoicedshipments(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pCusttypeid ALIAS FOR $2;
  _r RECORD;
  _recordCounter INTEGER := 0;

BEGIN

--  Grab all of the uninvoiced shipitem records
  FOR _r IN SELECT DISTINCT shiphead_id
            FROM shiphead, shipitem, coitem, itemsite, cohead, custinfo
            WHERE ( (shiphead_order_type='SO')
             AND (shipitem_shiphead_id=shiphead_id)
             AND (shipitem_orderitem_id=coitem_id)
             AND (coitem_itemsite_id=itemsite_id)
             AND (coitem_status <> 'C')
             AND (coitem_cohead_id=cohead_id)
             AND (cohead_cust_id=cust_id)
             AND (cust_custtype_id=pCusttypeid)
             AND ( (pWarehousid = -1) OR (itemsite_warehous_id=pWarehousid) )
             AND (shiphead_shipped)
             AND (NOT shipitem_invoiced)
             AND (coitem_id NOT IN ( SELECT cobill_coitem_id
                                     FROM cobmisc, cobill
                                     WHERE ((cobill_cobmisc_id=cobmisc_id)
                                      AND (NOT cobmisc_posted) ) ) ) ) LOOP

      PERFORM selectUninvoicedShipment(_r.shiphead_id);

    _recordCounter := _recordCounter + 1;

  END LOOP;

  RETURN _recordCounter;

END;

Function: public.selectuninvoicedshipments(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWarehousid ALIAS FOR $1;
  pCusttype ALIAS FOR $2;
  _r RECORD;
  _recordCounter INTEGER := 0;

BEGIN

--  Grab all of the uninvoiced shipitem records
  FOR _r IN SELECT DISTINCT shiphead_id
            FROM shiphead, shipitem, coitem, itemsite, cohead, custinfo, custtype
            WHERE ( (shiphead_order_type='SO')
             AND (shipitem_shiphead_id=shiphead_id)
             AND (shipitem_orderitem_id=coitem_id)
             AND (coitem_itemsite_id=itemsite_id)
             AND (coitem_status <> 'C')
             AND (coitem_cohead_id=cohead_id)
             AND (cohead_cust_id=cust_id)
             AND (cust_custtype_id=custtype_id)
             AND ( (pWarehousid = -1) OR (itemsite_warehous_id=pWarehousid) )
             AND (custtype_code ~ pCusttype)
             AND (shiphead_shipped)
             AND (NOT shipitem_invoiced)
             AND (coitem_id NOT IN ( SELECT cobill_coitem_id
                                     FROM cobmisc, cobill
                                     WHERE ((cobill_cobmisc_id=cobmisc_id)
                                      AND (NOT cobmisc_posted) ) ) ) ) LOOP

      PERFORM selectUninvoicedShipment(_r.shiphead_id);

    _recordCounter := _recordCounter + 1;

  END LOOP;

  RETURN _recordCounter;

END;

Function: public.setapjournalnumber()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _journalNumber INTEGER;
  _r RECORD;

BEGIN

--  Fetch the next Journal Number
  SELECT fetchJournalNumber('A/P') INTO _journalNumber;

--  Walk through all of the A/P Open Items
  FOR _r IN SELECT apopen_id, apopen_docnumber
            FROM apopen
            WHERE (NOT apopen_posted) LOOP

--  Set the Journal Number for all of the G/L Transactions
--  for the A/P Open Item
    UPDATE gltrans
    SET gltrans_journalnumber=_journalNumber
    WHERE ( (gltrans_source='P/O')
     AND (gltrans_doctype IN ('VO'))
     AND (gltrans_docnumber=_r.apopen_docnumber)
     AND (NOT gltrans_exported) );

--  Set the Journal Number for the A/P Open Item
    UPDATE apopen
    SET apopen_journalnumber=_journalNumber
    WHERE (apopen_id=_r.apopen_id);

  END LOOP;

  RETURN _journalNumber;

END;

Function: public.setarjournalnumber()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _journalNumber INTEGER;
  _r RECORD;

BEGIN

--  Fetch the next Journal Number
  SELECT fetchJournalNumber('A/R') INTO _journalNumber;

--  Walk through all of the A/R Open Items
  FOR _r IN SELECT aropen_id, aropen_docnumber
            FROM aropen
            WHERE (NOT aropen_posted) LOOP

--  Set the Journal Number for all of the G/L Transactions
--  for the A/R Open Item
    UPDATE gltrans
    SET gltrans_journalnumber=_journalNumber
    WHERE ( (gltrans_source='S/O')
     AND (gltrans_doctype IN ('CM', 'IN'))
     AND (gltrans_docnumber=_r.aropen_docnumber)
     AND (NOT gltrans_exported) );

--  Set the Journal Number for the A/R Open Item
    UPDATE aropen
    SET aropen_journalnumber=_journalNumber
    WHERE (aropen_id=_r.aropen_id);

  END LOOP;

  RETURN _journalNumber;

END;

Function: public.setbudget(integer, integer, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBudgheadid ALIAS FOR $1;
  pPeriodid ALIAS FOR $2;
  pAccntid ALIAS FOR $3;
  pAmount ALIAS FOR $4;
  _budgetid INTEGER;

BEGIN

  SELECT budgitem_id INTO _budgetid
    FROM budgitem
   WHERE ((budgitem_period_id=pPeriodid)
     AND  (budgitem_budghead_id=pBudgheadid)
     AND  (budgitem_accnt_id=pAccntid));
  IF (FOUND) THEN
    UPDATE budgitem
       SET budgitem_amount = pAmount
     WHERE (budgitem_id=_budgetid);
  ELSE
    SELECT nextval('budgitem_budgitem_id_seq') INTO _budgetid;

    INSERT INTO budgitem
          (budgitem_id, budgitem_budghead_id, budgitem_period_id, budgitem_accnt_id, budgitem_amount)
    VALUES(_budgetid, pBudgheadid, pPeriodid, pAccntid, pAmount);
  END IF;

  RETURN _budgetid;

END;

Function: public.setbudget(integer, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  pAccntid ALIAS FOR $2;
  pAmount ALIAS FOR $3;

BEGIN
  RETURN setBudget(1, pPeriodid, pAccntid, pAmount);
END;

Function: public.setbytea(bytea)

Returns: bytea

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMetricName ALIAS FOR $1;
  _value bytea;

BEGIN

  _value := pMetricName;

  RETURN _value;

END;

Function: public.setbytea(text)

Returns: bytea

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMetricName ALIAS FOR $1;
  _value bytea;

BEGIN

  _value := decode(pMetricName, 'escape');

  RETURN _value;

END;

Function: public.setccbankaccnt(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pccardtype   ALIAS FOR $1;
  pbankaccntid ALIAS FOR $2;

  _ccbankid    INTEGER;
  _numfound    INTEGER;

BEGIN
  RAISE DEBUG 'setCCBankAccount(%, %) entered', pccardtype, pbankaccntid;
  UPDATE ccbank SET ccbank_bankaccnt_id=pbankaccntid
  WHERE ccbank_ccard_type=pccardtype
  RETURNING ccbank_id INTO _ccbankid;

  GET DIAGNOSTICS _numfound = ROW_COUNT;

  IF (_numfound <= 0) THEN
    INSERT INTO ccbank (ccbank_ccard_type, ccbank_bankaccnt_id)
                VALUES (pccardtype,        pbankaccntid)
    RETURNING _ccbankid;
  END IF;

  RETURN _ccbankid;
END;

Function: public.seteffectivextuser(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
BEGIN
  PERFORM initEffectiveXtUser();

  PERFORM *
     FROM effective_user
    WHERE effective_key = 'username';

  IF FOUND THEN
    UPDATE effective_user
       SET effective_value = pUsername
     WHERE effective_key = 'username';
  ELSE
    INSERT INTO effective_user (effective_key, effective_value)
         VALUES('username', pUsername);
  END IF;

  RETURN true;
END;

Function: public.setgljournalnumber(date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStartDate ALIAS FOR $1;
  pEndDate ALIAS FOR $2;
  _journalNumber INTEGER;

BEGIN

--  Fetch the next Journal Number
  SELECT fetchJournalNumber('G/L') INTO _journalNumber;

--  Set the Journal Number for all of the unposted G/L Transactions
--  in the passed date range.
  UPDATE gltrans
  SET gltrans_journalnumber=_journalNumber
  WHERE ( (NOT gltrans_exported)
    AND (gltrans_date BETWEEN pStartDate and pEndDate) );

  RETURN _journalNumber;

END;

Function: public.setmetric(text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMetricName ALIAS FOR $1;
  pMetricValue ALIAS FOR $2;
  _metricid INTEGER;

BEGIN

  SELECT metric_id INTO _metricid
  FROM metric
  WHERE (metric_name=pMetricName);

  IF (FOUND) THEN
    UPDATE metric
    SET metric_value=pMetricValue
    WHERE (metric_id=_metricid);

  ELSE
    INSERT INTO metric
    (metric_name, metric_value)
    VALUES (pMetricName, pMetricValue);
  END IF;

  RETURN TRUE;

END;

Function: public.setmetricenc(text, text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMetricName ALIAS FOR $1;
  pMetricValue ALIAS FOR $2;
  pMetricEnc ALIAS FOR $3;
  _metricid INTEGER;
  _value bytea;
  _key bytea;

BEGIN

  _value = decode(pMetricValue, 'escape');
  _key = decode(pMetricEnc, 'escape');

  SELECT metricenc_id INTO _metricid
  FROM metricenc
  WHERE (metricenc_name=pMetricName);

  IF (FOUND) THEN
    UPDATE metricenc
    SET metricenc_value=encrypt(_value, _key, 'bf')
    WHERE (metricenc_id=_metricid);

  ELSE
    INSERT INTO metricenc
    (metricenc_name, metricenc_value)
    VALUES (pMetricName, encrypt(_value, _key, 'bf'));
  END IF;

  RETURN TRUE;

END;

Function: public.setnextapmemonumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='APMemoNumber');
  IF (FOUND) THEN
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_id=_orderseqid);

  ELSE
    INSERT INTO orderseq
    (orderseq_name, orderseq_number)
    VALUES
    ('APMemoNumber', pNumber);
  END IF;

  RETURN 1;

END;

Function: public.setnextarmemonumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='ARMemoNumber');
  IF (FOUND) THEN
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_id=_orderseqid);

  ELSE
    INSERT INTO orderseq
    (orderseq_name, orderseq_number)
    VALUES
    ('ARMemoNumber', pNumber);
  END IF;

  RETURN 1;

END;

Function: public.setnextcashrcptnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='CashRcptNumber');
  IF (FOUND) THEN
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_id=_orderseqid);

  ELSE
    INSERT INTO orderseq
    (orderseq_name, orderseq_number)
    VALUES
    ('CashRcptNumber', pNumber);
  END IF;

  RETURN 1;

END;

Function: public.setnextchecknumber(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankaccntid ALIAS FOR $1;
  pNextCheckNumber ALIAS FOR $2;

BEGIN

  UPDATE bankaccnt
  SET bankaccnt_nextchknum=pNextCheckNumber
  WHERE (bankaccnt_id=pBankaccntid);

  RETURN TRUE;

END;

Function: public.setnextcmnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='CmNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'CmNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='CmNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextcrmaccountnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='CRMAccountNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'CRMAccountNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='CRMAccountNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextincidentnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='IncidentNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'IncidentNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='IncidentNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextinvcnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='InvcNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'InvcNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='InvcNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextnumber(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  psequence	ALIAS FOR $1;
  pnumber	ALIAS FOR $2;
  _orderseqid	INTEGER;

BEGIN
  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name=psequence);

  IF (NOT FOUND) THEN
    INSERT INTO orderseq (orderseq_name, orderseq_number,
			  orderseq_table, orderseq_numcol)
		  VALUES (psequence,     pnumber,
			  CASE WHEN (psequence='APMemoNumber') THEN 'apopen'
			       WHEN (psequence='ARMemoNumber') THEN 'aropen'
			       WHEN (psequence='CmNumber') THEN 'cmhead'
			       WHEN (psequence='IncidentNumber') THEN 'incdt'
			       WHEN (psequence='InvcNumber') THEN 'invchead'
			       WHEN (psequence='JournalNumber') THEN 'gltrans'
			       WHEN (psequence='PlanNumber') THEN 'planord'
			       WHEN (psequence='PoNumber') THEN 'pohead'
			       WHEN (psequence='PrNumber') THEN 'pr'
			       WHEN (psequence='QuNumber') THEN 'quhead'
			       WHEN (psequence='ShipmentNumber') THEN 'shiphead'
			       WHEN (psequence='SoNumber') THEN 'cohead'
			       WHEN (psequence='ToNumber') THEN 'tohead'
			       WHEN (psequence='VcNumber') THEN 'vohead'
			       WHEN (psequence='WoNumber') THEN 'wo'
			       ELSE ''
			  END,
			  CASE WHEN (psequence='APMemoNumber') THEN 'apopen_docnumber'
			       WHEN (psequence='ARMemoNumber') THEN 'aropen_docnumber'
			       WHEN (psequence='CmNumber') THEN 'cmhead_number'
			       WHEN (psequence='IncidentNumber') THEN 'incdt_number'
			       WHEN (psequence='InvcNumber') THEN 'invchead_invcnumber'
			       WHEN (psequence='JournalNumber') THEN 'gltrans_journalnumber'
			       WHEN (psequence='PlanNumber') THEN 'planord_number'
			       WHEN (psequence='PoNumber') THEN 'pohead_number'
			       WHEN (psequence='PrNumber') THEN 'pr_number'
			       WHEN (psequence='QuNumber') THEN 'quhead_number'
			       WHEN (psequence='ShipmentNumber') THEN 'shiphead_number'
			       WHEN (psequence='SoNumber') THEN 'cohead_number'
			       WHEN (psequence='ToNumber') THEN 'tohead_number'
			       WHEN (psequence='VcNumber') THEN 'vohead_number'
			       WHEN (psequence='WoNumber') THEN 'wo_number'
			       ELSE ''
			  END
			  );
  ELSE
    UPDATE orderseq
    SET orderseq_number=pnumber
    WHERE (orderseq_name=psequence);
  END IF;

  RETURN 0;
END;

Function: public.setnextponumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='PoNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;
    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'PoNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='PoNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextprnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='PrNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;
    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'PrNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='PrNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextqunumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pQuNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='QuNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'QuNumber', pQuNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pQuNumber
    WHERE (orderseq_name='QuNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextshipmentnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pShipmentNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='ShipmentNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'ShipmentNumber', pShipmentNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pShipmentNumber
    WHERE (orderseq_name='ShipmentNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextsonumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSoNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='SoNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'SoNumber', pSoNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pSoNumber
    WHERE (orderseq_name='SoNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextvcnumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='VcNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;
    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'VcNumber', pNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pNumber
    WHERE (orderseq_name='VcNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setnextwonumber(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pWoNumber ALIAS FOR $1;
  _orderseqid INTEGER;

BEGIN

  SELECT orderseq_id INTO _orderseqid
  FROM orderseq
  WHERE (orderseq_name='WoNumber');

  IF (NOT FOUND) THEN
    SELECT NEXTVAL('orderseq_orderseq_id_seq') INTO _orderseqid;

    INSERT INTO orderseq (orderseq_id, orderseq_name, orderseq_number)
    VALUES (_orderseqid, 'WoNumber', pWoNumber);

  ELSE
    UPDATE orderseq
    SET orderseq_number=pWoNumber
    WHERE (orderseq_name='WoNumber');
  END IF;

  RETURN _orderseqid;

END;

Function: public.setusercancreateusers(pcreateuser text, pusername boolean)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  IF (pCreateUser) THEN
    EXECUTE 'ALTER USER ' || pUsername || ' CREATEROLE;';
  ELSE
    EXECUTE 'ALTER USER ' || pUsername || ' NOCREATEROLE;';
  END IF;
  RETURN TRUE;
END;

Function: public.setuserpreference(text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPrefName ALIAS FOR $1;
  pPrefValue ALIAS FOR $2;

BEGIN
  RETURN setUserPreferences(getEffectiveXtUser(), pPrefName, pPrefValue);
END;

Function: public.setuserpreference(text, text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  pPrefName ALIAS FOR $2;
  pPrefValue ALIAS FOR $3;
  _usrprefid INTEGER;

BEGIN

  SELECT usrpref_id INTO _usrprefid
  FROM usrpref
  WHERE ( (usrpref_username=pUsername)
   AND (usrpref_name=pPrefName) );

  IF (FOUND) THEN
    UPDATE usrpref
    SET usrpref_value=pPrefValue
    WHERE (usrpref_id=_usrprefid);

  ELSE
    INSERT INTO usrpref
    (usrpref_username, usrpref_name, usrpref_value)
    VALUES
    (pUsername, pPrefName, pPrefValue);
  END IF;

  RETURN TRUE;

END;

Function: public.shipments(text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;

BEGIN
  IF (pTransType IN ('SC', 'SV', 'SH', 'RS', 'TS')) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.shipshipment(integer)

Returns: integer

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
  SELECT shipShipment($1, CURRENT_TIMESTAMP);

Function: public.shipshipment(integer, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pshipheadid		ALIAS FOR $1;
  _timestamp		TIMESTAMP WITH TIME ZONE := $2;

  _billedQty		NUMERIC;
  _c			RECORD;
  _coholdtype		TEXT;
  _gldate		DATE;
  _invhistid		INTEGER;
  _itemlocSeries	INTEGER;
  _lineitemsToClose     INTEGER[];
  _newQty		NUMERIC;
  _result		INTEGER;
  _s			RECORD;
  _shipcomplete		BOOLEAN;
  _shiphead		RECORD;
  _ti			RECORD;
  _to			RECORD;
  _variance           	NUMERIC;
  _k                    RECORD;

BEGIN

  IF (_timestamp IS NULL) THEN
    _timestamp := CURRENT_TIMESTAMP;
  END IF;
  _gldate := _timestamp::DATE;

  SELECT * INTO _shiphead
  FROM shiphead WHERE (shiphead_id=pshipheadid);
  IF (NOT FOUND) THEN
    RETURN -50;
  END IF;

  IF (_shiphead.shiphead_order_type = 'SO') THEN

    SELECT cohead_shipcomplete, cohead_holdtype INTO _shipcomplete, _coholdtype
      FROM cohead, shiphead
     WHERE ((shiphead_order_id=cohead_id)
       AND  (NOT shiphead_shipped)
       AND  (shiphead_order_type=_shiphead.shiphead_order_type)
       AND  (shiphead_id=pshipheadid));

    IF (_coholdtype = 'C') THEN
      RETURN -12;
    ELSIF (_coholdtype = 'P') THEN
      RETURN -13;
    ELSIF (_coholdtype = 'R') THEN
      RETURN -14;
    ELSIF (_coholdtype = 'S') THEN
      RETURN -15;
    END IF;

---Must Ship Kit components (coitem_subnumber <> 0 complete---------------
    IF ((
         --  Test to see if order's customer accepts backorders and partials 
         --  If not then test for shipping kit components complete 
        SELECT cohead_number
        FROM shiphead, cohead, custinfo
        WHERE 
          (shiphead_order_id = cohead_id) AND
          (cohead_cust_id = cust_id) AND
          (shiphead_order_type = 'SO') AND 
          (cust_partialship) AND
          (cust_backorder) AND
          (shiphead_id = pshipheadid)
         ) IS NULL) THEN
      FOR _k IN SELECT (coitem_qtyord -
			(COALESCE(SUM(shipitem_qty),0) +
			 (coitem_qtyshipped - coitem_qtyreturned))) AS remain
		  FROM (coitem LEFT OUTER JOIN (itemsite JOIN item ON (itemsite_item_id=item_id)) ON (coitem_itemsite_id=itemsite_id)) LEFT OUTER JOIN
		       shipitem ON (shipitem_orderitem_id=coitem_id
		                AND shipitem_shiphead_id=pshipheadid)
		 WHERE ((coitem_status NOT IN ('C','X'))
                   AND  (item_type != 'K')
		   AND  (coitem_cohead_id=_shiphead.shiphead_order_id)
                   AND  (coitem_subnumber <> 0)
		   )
	      GROUP BY coitem_id, coitem_qtyshipped, coitem_qtyord,
		       coitem_qtyreturned LOOP
	IF (_k.remain > 0) THEN
	  RAISE EXCEPTION 'Kit component item not shipped complete.  Kits must be shipped and shipped complete or closed on the order.';
	END IF;
      END LOOP;
    END IF;
---End--------------------------------------------------------------------

    IF ( _shipcomplete ) THEN
      FOR _c IN SELECT (coitem_qtyord -
			(COALESCE(SUM(shipitem_qty),0) +
			 (coitem_qtyshipped - coitem_qtyreturned))) AS remain
		  FROM (coitem LEFT OUTER JOIN (itemsite JOIN item ON (itemsite_item_id=item_id)) ON (coitem_itemsite_id=itemsite_id)) LEFT OUTER JOIN
		       shipitem ON (shipitem_orderitem_id=coitem_id
		                AND shipitem_shiphead_id=pshipheadid)
		 WHERE ((coitem_status<>'X')
                   AND  (item_type != 'K')
		   AND  (coitem_cohead_id=_shiphead.shiphead_order_id))
	      GROUP BY coitem_id, coitem_qtyshipped, coitem_qtyord,
		       coitem_qtyreturned LOOP
	IF (_c.remain > 0) THEN
	  RETURN -99;
	END IF;
      END LOOP;
    END IF;

    FOR _c IN SELECT coitem_id, cohead_number, cohead_cust_id, cohead_billtoname, cohead_prj_id,
                     cohead_saletype_id, cohead_shipzone_id,
		     itemsite_id, itemsite_item_id,
                     coitem_qty_invuomratio,
                     coitem_warranty, coitem_cos_accnt_id,
		     SUM(shipitem_qty) AS _qty,
                     SUM(shipitem_value) AS _value
	      FROM coitem, cohead, shiphead, shipitem, itemsite
	      WHERE ( (coitem_cohead_id=cohead_id)
	       AND (coitem_itemsite_id=itemsite_id)
	       AND (shiphead_order_id=cohead_id)
	       AND (shipitem_shiphead_id=shiphead_id)
	       AND (shipitem_orderitem_id=coitem_id)
	       AND (NOT shiphead_shipped)
	       AND (shiphead_id=pshipheadid) )
	      GROUP BY coitem_id, coitem_qty_invuomratio, cohead_number, cohead_cust_id, cohead_billtoname,
           itemsite_id, itemsite_item_id, coitem_warranty, coitem_cos_accnt_id, cohead_prj_id, cohead_saletype_id, cohead_shipzone_id
    LOOP

      IF _c._value > 0 THEN
  --    Distribute to G/L, credit Shipping Asset, debit COS
	SELECT MIN(insertGLTransaction( 'S/R', 'SH', _shiphead.shiphead_number,
                                        ('Ship Order ' || _c.cohead_number || ' for Customer ' || _c.cohead_billtoname),
                                        getPrjAccntId(_c.cohead_prj_id, costcat_shipasset_accnt_id),
                                        CASE WHEN (COALESCE(_c.coitem_cos_accnt_id, -1) != -1)
                                               THEN getPrjAccntId(_c.cohead_prj_id, _c.coitem_cos_accnt_id)
                                             WHEN (_c.coitem_warranty=TRUE)
                                               THEN getPrjAccntId(_c.cohead_prj_id, resolveCOWAccount(itemsite_id, _c.cohead_cust_id, _c.cohead_saletype_id, _c.cohead_shipzone_id))
                                             ELSE getPrjAccntId(_c.cohead_prj_id, resolveCOSAccount(itemsite_id, _c.cohead_cust_id, _c.cohead_saletype_id, _c.cohead_shipzone_id))
                                        END,
                                        -1, _c._value, _gldate )) INTO _result
	FROM itemsite, costcat
	WHERE ( (itemsite_costcat_id=costcat_id)
	AND (itemsite_id=_c.itemsite_id) );

	IF (_result < 0 AND _result != -3) THEN -- ignore -3 as it just means it's not posting a 0 value
	  RETURN _result;
	END IF;

      END IF;

      UPDATE coitem
      SET coitem_qtyshipped = (coitem_qtyshipped + _c._qty)
      WHERE (coitem_id=_c.coitem_id);

      -- check to see if we have more invoiced than shipped items
      -- if we do we will need to mark some of these records as invoiced
      SELECT noNeg(( SELECT COALESCE(SUM(cobill_qty), 0.0)
		     FROM cobill, cobmisc, coitem
		     WHERE ( (cobill_cobmisc_id=cobmisc_id)
		      AND (cobmisc_cohead_id=coitem_cohead_id)
		      AND (cobill_coitem_id=coitem_id)
		      AND (cobmisc_posted)
		      AND (coitem_id=_c.coitem_id) )
		   ) - ( SELECT COALESCE(SUM(shipitem_qty), 0.0)
			 FROM shipitem, shiphead, coitem
			 WHERE ( (shipitem_shiphead_id=shiphead_id)
			  AND (shiphead_order_id=coitem_cohead_id)
			  AND (shipitem_orderitem_id=coitem_id)
			  AND (shiphead_order_type=_shiphead.shiphead_order_type)
			  AND (shiphead_shipped)
			  AND (coitem_id=_c.coitem_id) )
		       ) ) INTO _billedQty;

      IF (_billedQty > 0.0) THEN
	FOR _s IN SELECT shipitem_id, shipitem_qty
		  FROM shipitem, shiphead
		  WHERE ( (shipitem_shiphead_id=shiphead_id)
		   AND (shipitem_orderitem_id=_c.coitem_id)
		   AND (shiphead_order_type=_shiphead.shiphead_order_type)
		   AND (NOT shiphead_shipped)
		   AND (shiphead_id=pshipheadid) )
		  ORDER BY shipitem_qty LOOP

	  IF (_billedQty > 0.0) THEN

	    IF (_billedQty >= _s.shipitem_qty) THEN
	      UPDATE shipitem SET shipitem_invoiced=TRUE WHERE shipitem_id=_s.shipitem_id;
              -- must wait to close coitems until after shiphead_shipped -> true
              _lineitemsToClose := _lineitemsToClose || _c.coitem_id;
	    ELSE
	      _newQty := _s.shipitem_qty - _billedQty;
	      UPDATE shipitem SET shipitem_invoiced=TRUE, shipitem_qty=_billedQty WHERE shipitem_id=_s.shipitem_id;
	      INSERT INTO shipitem ( shipitem_orderitem_id, shipitem_shipdate,
		shipitem_qty, shipitem_transdate, shipitem_invoiced,
		shipitem_shiphead_id, shipitem_trans_username)
	      SELECT shipitem_orderitem_id, shipitem_shipdate,
		_newQty, shipitem_transdate, FALSE,
		shipitem_shiphead_id, shipitem_trans_username
	      FROM shipitem
	      WHERE (shipitem_id=_s.shipitem_id);
	    END IF;

	    _billedQty := _billedQty - _s.shipitem_qty;
	  END IF;
	END LOOP;

      END IF;
    END LOOP;

  ELSEIF (_shiphead.shiphead_order_type = 'TO') THEN
    IF (_shiphead.shiphead_shipped) THEN
      RETURN -8;
    END IF;

    SELECT tohead.* INTO _to
      FROM tohead
     WHERE (tohead_id=_shiphead.shiphead_order_id);

    IF ( _to.tohead_shipcomplete ) THEN
      -- use sufficientInventory...()?
      FOR _ti IN SELECT (toitem_qty_ordered -
			 (COALESCE(SUM(shipitem_qty),0) + toitem_qty_shipped)) AS remain
		  FROM toitem LEFT OUTER JOIN
		       shipitem ON (shipitem_orderitem_id=toitem_id)
		 WHERE ((toitem_status<>'X')
		   AND  (toitem_tohead_id=_shiphead.shiphead_order_id))
	      GROUP BY toitem_qty_shipped, toitem_qty_ordered LOOP
	IF (_ti.remain > 0) THEN
	  RETURN -99;
	END IF;
      END LOOP;
    END IF;

    FOR _ti IN SELECT toitem_id, toitem_item_id, SUM(shipitem_qty) AS qty, SUM(shipitem_value) AS value
		FROM toitem, shipitem
		WHERE ((toitem_tohead_id=_to.tohead_id)
		  AND  (shipitem_orderitem_id=toitem_id)
		  AND  (shipitem_shiphead_id=pshipheadid))
		GROUP BY toitem_id, toitem_item_id LOOP

      IF (NOT EXISTS(SELECT itemsite_id
		     FROM itemsite
		     WHERE ((itemsite_item_id=_ti.toitem_item_id)
		     AND  (itemsite_warehous_id = _to.tohead_trns_warehous_id))
		     )) THEN
	RETURN -6;
      END IF;

      _itemlocSeries := NEXTVAL('itemloc_series_seq');

      SELECT postInvTrans(si.itemsite_id, 'TS', _ti.qty,
                          'I/M', _shiphead.shiphead_order_type,
                          formatToNumber(_ti.toitem_id), _to.tohead_number,
			  'Ship from Src to Transit Warehouse',
			  tc.costcat_asset_accnt_id,
			  sc.costcat_shipasset_accnt_id,
			  _itemlocSeries, _timestamp, _ti.value) INTO _invhistid
      FROM itemsite AS ti, costcat AS tc,
	   itemsite AS si, costcat AS sc
      WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
        AND  (si.itemsite_costcat_id=sc.costcat_id)
        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
        AND  (si.itemsite_item_id=_ti.toitem_item_id)
        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id)
        AND  (si.itemsite_warehous_id=_to.tohead_src_warehous_id) );

      --We do not need to distribute lot/serial info for transit, post trans and discard dist detail
      PERFORM postIntoTrialBalance(itemlocpost_glseq) FROM itemlocpost WHERE (itemlocpost_itemlocseries=_itemlocSeries);
      PERFORM postInvHist(_invhistid);
      DELETE FROM itemlocdist WHERE (itemlocdist_series=_itemlocSeries);
      DELETE FROM itemlocpost WHERE (itemlocpost_itemlocSeries=_itemlocSeries);

      IF (_result < 0) THEN
	RETURN _result;
      END IF;

      -- record inventory history and qoh changes at transit warehouse but
      -- there is only one g/l account to touch
      SELECT postInvTrans(ti.itemsite_id, 'TR', _ti.qty,
                          'I/M', _shiphead.shiphead_order_type,
                          formatToNumber(_ti.toitem_id), _to.tohead_number,
			  'Receive into Transit from Src Warehouse',
			  tc.costcat_asset_accnt_id,
			  tc.costcat_asset_accnt_id,
			  _itemlocSeries, _timestamp, 
			  _ti.value) INTO _invhistid
      FROM itemsite AS ti, costcat AS tc
      WHERE ((ti.itemsite_costcat_id=tc.costcat_id)
        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id));
      --We do not need to distribute lot/serial info for transit, post trans and discard dist detail
      PERFORM postIntoTrialBalance(itemlocpost_glseq) FROM itemlocpost WHERE (itemlocpost_itemlocseries=_itemlocSeries);
      PERFORM postInvHist(_invhistid);
      DELETE FROM itemlocdist WHERE (itemlocdist_series=_itemlocSeries);
      DELETE FROM itemlocpost WHERE (itemlocpost_itemlocSeries=_itemlocSeries);

      --See if there was a change in values during the transfer, if so record the variance
      SELECT (invhist_invqty * invhist_unitcost - _ti.value) INTO _variance
      FROM invhist
      WHERE (invhist_id=_invhistid);

      IF (_variance > 0) THEN
        PERFORM insertGLTransaction( 'S/R', _shiphead.shiphead_order_type, _to.tohead_number, 
                                     'Transfer Order - Transfer Variance',
                                     tc.costcat_invcost_accnt_id, tc.costcat_asset_accnt_id, _invhistid,
                                     _variance,
                                     CAST(_timestamp AS DATE) )
        FROM itemsite AS ti, costcat AS tc
        WHERE ( (ti.itemsite_costcat_id=tc.costcat_id)
        AND  (ti.itemsite_item_id=_ti.toitem_item_id)
        AND  (ti.itemsite_warehous_id=_to.tohead_trns_warehous_id) );
      END IF;

      IF (_result < 0) THEN
	RETURN _result;
      END IF;

      UPDATE shipitem SET shipitem_shipdate=_timestamp, shipitem_shipped=TRUE
      WHERE ((shipitem_orderitem_id=_ti.toitem_id)
        AND  (shipitem_shiphead_id=pshipheadid));

      UPDATE toitem
      SET toitem_qty_shipped = (toitem_qty_shipped + _ti.qty)
      WHERE (toitem_id=_ti.toitem_id);
    END LOOP;
  END IF;

  UPDATE shiphead
  SET shiphead_shipped=TRUE, shiphead_shipdate=_gldate
  WHERE (shiphead_id=pshipheadid);

  -- now try to close line items that are fully shipped and invoiced
  IF (_shiphead.shiphead_order_type = 'SO') THEN
    UPDATE coitem SET coitem_status='C'
    WHERE ((coitem_id = ANY (_lineitemsToClose))
      AND  (coitem_qtyshipped >= coitem_qtyord));
  END IF;

  RETURN _itemlocSeries;

END;

Function: public.singlecharacteristicstostring(text, integer, text, text, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetType ALIAS FOR $1;
  pTargetId ALIAS FOR $2;
  pValKeySep ALIAS FOR $3;
  pPairSep ALIAS FOR $4;
  pCharId ALIAS FOR $5;
  _string TEXT := '';
  _extra BOOLEAN := false;
  _r RECORD;
BEGIN
  FOR _r IN SELECT char_name, charass_value
              FROM charass, char
             WHERE ((charass_char_id=char_id)
               AND  (charass_char_id=pCharId)
               AND  (charass_target_type=pTargetType)
               AND  (charass_target_id=pTargetId)) LOOP
    IF(_extra) THEN
      _string := _string || pPairSep;
    END IF;
    _extra := true;

    _string := _string || _r.char_name || pValKeySep || _r.charass_value;
  END LOOP;

  RETURN _string;
END;

Function: public.singlelevelbom(integer, integer, integer, integer)

Returns: SET OF bomdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  pExpiredDays ALIAS FOR $3;
  pFutureDays ALIAS FOR $4;
  _row bomdata%ROWTYPE;
  _bomworksetid INTEGER;
  _x RECORD;
  _check CHAR(1);
  _inactive BOOLEAN;
  _batchsize NUMERIC;

BEGIN

  _inactive := FALSE;

  IF (pRevisionid != -1) THEN
    --Is this a deactivated revision?
    SELECT rev_status INTO _check
    FROM rev
    WHERE ((rev_id=pRevisionid)
    AND (rev_status='I'));
    IF (FOUND) THEN
      _inactive := TRUE;
    END IF;
  END IF;
 
  -- Get the batch quantity
  SELECT COALESCE( (
    SELECT bomhead_batchsize
    FROM bomhead
    WHERE ((bomhead_item_id=pItemId)
    AND (bomhead_rev_id=pRevisionid))),1) INTO _batchsize;
 
  IF NOT (_inactive) THEN
    FOR _x IN
        SELECT bomitem_id, bomitem_seqnumber, bomitem_seqnumber AS f_bomitem_seqnumber,
               item_id, item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyfxd) AS qtyfxd,
               (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyper) AS qtyper,
               bomitem_scrap, bomitem_createwo,
               CASE WHEN (bomitem_issuemethod='S') THEN 'Push'
                 WHEN (bomitem_issuemethod='L') THEN 'Pull'
                 WHEN (bomitem_issuemethod='M') THEN 'Mixed'
                 ELSE 'Special'
               END AS issuemethod,
               bomitem_effective, bomitem_expires,
               CASE WHEN (bomitem_expires <= CURRENT_DATE) THEN TRUE
                 ELSE FALSE
               END AS expired,
               CASE WHEN (bomitem_effective > CURRENT_DATE) THEN TRUE
                 ELSE FALSE
               END AS future,
               actcost(bomitem_item_id, bomitem_id) AS actunitcost,
               stdcost(bomitem_item_id, bomitem_id) AS stdunitcost,
               CASE WHEN item_type NOT IN ('R','T') THEN
                 (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) *
                  (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap)) * actcost(bomitem_item_id, bomitem_id)
               ELSE 0 END AS actextendedcost,
               CASE WHEN item_type NOT IN ('R','T') THEN
                 (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) *
                  (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap)) * stdcost(bomitem_item_id, bomitem_id)
               ELSE 0 END AS stdextendedcost,
               bomitem_char_id, bomitem_value, bomitem_notes, bomitem_ref 
       FROM bomitem(pItemid,pRevisionid), item, uom 
       WHERE ( (item_inv_uom_id=uom_id)
       AND (bomitem_item_id=item_id)
       AND (bomitem_expires > (CURRENT_DATE - pExpiredDays))
       AND (bomitem_effective <= (CURRENT_DATE + pFutureDays)) )
       UNION
       SELECT -1, -1, NULL, -1, costelem_type AS bomdata_item_number, '',
              '', '',
              '',
              NULL,
              NULL,
              NULL, NULL,
              NULL,
              NULL, NULL,
              false,false,
              currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) AS actunitcost,
              itemcost_stdcost AS stdunitcost,
              currToBase(itemcost_curr_id, itemcost_actcost, CURRENT_DATE) AS actextendedcost,
              itemcost_stdcost AS stdextendedcost,
              NULL, NULL, NULL, NULL
       FROM itemcost, costelem 
       WHERE ( (itemcost_costelem_id=costelem_id)
       AND (NOT itemcost_lowlevel)
       AND (itemcost_item_id=pItemid) )
       ORDER BY bomitem_seqnumber, bomitem_effective, item_number
    LOOP
        _row.bomdata_bomitem_id := _x.bomitem_id;
        _row.bomdata_bomwork_seqnumber := _x.f_bomitem_seqnumber;
        _row.bomdata_item_id := _x.item_id;
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_batchsize := _batchsize;
        _row.bomdata_qtyfxd := _x.qtyfxd;
        _row.bomdata_qtyper := _x.qtyper;
        _row.bomdata_scrap := _x.bomitem_scrap;
        _row.bomdata_createchild := _x.bomitem_createwo;
        _row.bomdata_issuemethod := _x.issuemethod;
        _row.bomdata_effective := _x.bomitem_effective;
        _row.bomdata_expires := _x.bomitem_expires;
        _row.bomdata_expired := _x.expired;
        _row.bomdata_future := _x.future;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        _row.bomdata_char_id := _x.bomitem_char_id;
        _row.bomdata_value := _x.bomitem_value;
        _row.bomdata_notes := _x.bomitem_notes;
        _row.bomdata_ref := _x.bomitem_ref;
        RETURN NEXT _row;
    END LOOP;

   ELSE

-- Use historical snapshot for inactive revisions
    FOR _x IN
        SELECT bomitem_id, bomitem_seqnumber, bomitem_seqnumber AS f_bomitem_seqnumber,
               item_id, item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyfxd) AS qtyfxd,
               (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) * bomitem_qtyper) AS qtyper,
               bomitem_scrap, bomitem_createwo,
               CASE WHEN (bomitem_issuemethod='S') THEN 'Push'
                 WHEN (bomitem_issuemethod='L') THEN 'Pull'
                 WHEN (bomitem_issuemethod='M') THEN 'Mixed'
                 ELSE 'Special'
               END AS issuemethod,
               bomitem_effective, bomitem_expires,
               CASE WHEN (bomitem_expires <= CURRENT_DATE) THEN TRUE
                 ELSE FALSE
               END AS expired,
               CASE WHEN (bomitem_effective > CURRENT_DATE) THEN TRUE
                 ELSE FALSE
               END AS future,
               actcost(bomitem_item_id) AS actunitcost,
               stdcost(bomitem_item_id) AS stdunitcost,
               CASE WHEN item_type NOT IN ('R','T') THEN
                 (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) *
                  (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap)) * actcost(bomitem_item_id)
               ELSE 0 END AS actextendedcost,
               CASE WHEN item_type NOT IN ('R','T') THEN
                 (itemuomtouomratio(bomitem_item_id, bomitem_uom_id, NULL) *
                  (bomitem_qtyfxd/_batchsize + bomitem_qtyper) * (1 + bomitem_scrap)) * stdcost(bomitem_item_id)
               ELSE 0 END AS stdextendedcost,
               bomitem_char_id, bomitem_value, bomitem_notes, bomitem_ref 
       FROM bomitem(pItemid,pRevisionid), item, uom 
       WHERE ( (item_inv_uom_id=uom_id)
       AND (bomitem_item_id=item_id)
       AND (bomitem_expires > (CURRENT_DATE - pExpiredDays))
       AND (bomitem_effective <= (CURRENT_DATE + pFutureDays)) )
       UNION
       SELECT -1, -1, NULL, -1, costelem_type AS bomdata_item_number, '',
              '', '',
              '',
              NULL,
              NULL,
              NULL, NULL,
              NULL,
              NULL, NULL,
              false,false,
              bomhist_actunitcost AS actunitcost,
              bomhist_stdunitcost AS stdunitcost,
              bomhist_actunitcost AS actextendedcost,
              bomhist_stdunitcost AS stdextendedcost,
              NULL, NULL, NULL, NULL
       FROM bomhist, costelem 
       WHERE ( (bomhist_item_id=costelem_id)
       AND (bomhist_item_type='E')
       AND (bomhist_rev_id=pRevisionid) )
       ORDER BY bomitem_seqnumber, bomitem_effective, item_number
    LOOP
        _row.bomdata_bomitem_id := _x.bomitem_id;
        _row.bomdata_bomwork_seqnumber := _x.f_bomitem_seqnumber;
        _row.bomdata_item_id := _x.item_id;
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_batchsize := _batchsize;
        _row.bomdata_qtyfxd := _x.qtyfxd;
        _row.bomdata_qtyper := _x.qtyper;
        _row.bomdata_scrap := _x.bomitem_scrap;
        _row.bomdata_createchild := _x.bomitem_createwo;
        _row.bomdata_issuemethod := _x.issuemethod;
        _row.bomdata_effective := _x.bomitem_effective;
        _row.bomdata_expires := _x.bomitem_expires;
        _row.bomdata_expired := _x.expired;
        _row.bomdata_future := _x.future;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        _row.bomdata_char_id := _x.bomitem_char_id;
        _row.bomdata_value := _x.bomitem_value;
        _row.bomdata_notes := _x.bomitem_notes;
        _row.bomdata_ref := _x.bomitem_ref;
        RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;
END;

Function: public.site()

Returns: SET OF whsinfo

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row whsinfo%ROWTYPE;
  _r RECORD;

BEGIN

  IF ( (fetchMetricBool('MultiWhs')) AND
       (SELECT (COUNT(usrpref_id)=1)
        FROM usrpref
        WHERE ((usrpref_name='selectedSites')
        AND (usrpref_value='t')
        AND (usrpref_username=getEffectiveXtUser()))) ) THEN

    FOR _r IN SELECT *
            FROM whsinfo,usrsite
            WHERE ((warehous_id=usrsite_warehous_id)
            AND (usrsite_username=getEffectiveXtUser()))
    LOOP
      _row.warehous_id:=_r.warehous_id;
      _row.warehous_code:=_r.warehous_code;
      _row.warehous_descrip:=_r.warehous_descrip;
      _row.warehous_fob:=_r.warehous_fob;
      _row.warehous_active:=_r.warehous_active;
      _row.warehous_counttag_prefix:=_r.warehous_counttag_prefix;
      _row.warehous_counttag_number:=_r.warehous_counttag_number;
      _row.warehous_bol_prefix:=_r.warehous_bol_prefix;
      _row.warehous_bol_number:=_r.warehous_bol_number;
      _row.warehous_shipping:=_r.warehous_shipping;
      _row.warehous_useslips:=_r.warehous_useslips;
      _row.warehous_usezones:=_r.warehous_usezones;
      _row.warehous_aislesize:=_r.warehous_aislesize;
      _row.warehous_racksize:=_r.warehous_racksize;
      _row.warehous_binsize:=_r.warehous_binsize;
      _row.warehous_binalpha:=_r.warehous_binalpha;
      _row.warehous_locationsize:=_r.warehous_locationsize;
      _row.warehous_locationalpha:=_r.warehous_locationalpha;
      _row.warehous_enforcearbl:=_r.warehous_enforcearbl;
      _row.warehous_default_accnt_id:=_r.warehous_default_accnt_id;
      _row.warehous_shipping_commission:=_r.warehous_shipping_commission;
      _row.warehous_cntct_id:=_r.warehous_cntct_id;
      _row.warehous_addr_id:=_r.warehous_addr_id;
      _row.warehous_taxzone_id:=_r.warehous_taxzone_id;
      _row.warehous_transit:=_r.warehous_transit;
      _row.warehous_shipform_id:=_r.warehous_shipform_id;
      _row.warehous_shipvia_id:=_r.warehous_shipvia_id;
      _row.warehous_shipcomments:=_r.warehous_shipcomments;
      _row.warehous_costcat_id:=_r.warehous_costcat_id;
      _row.warehous_sitetype_id:=_r.warehous_sitetype_id;
             
      RETURN NEXT _row;
    END LOOP;
  ELSE
    FOR _r IN SELECT *
            FROM whsinfo
    LOOP
      _row.warehous_id:=_r.warehous_id;
      _row.warehous_code:=_r.warehous_code;
      _row.warehous_descrip:=_r.warehous_descrip;
      _row.warehous_fob:=_r.warehous_fob;
      _row.warehous_active:=_r.warehous_active;
      _row.warehous_counttag_prefix:=_r.warehous_counttag_prefix;
      _row.warehous_counttag_number:=_r.warehous_counttag_number;
      _row.warehous_bol_prefix:=_r.warehous_bol_prefix;
      _row.warehous_bol_number:=_r.warehous_bol_number;
      _row.warehous_shipping:=_r.warehous_shipping;
      _row.warehous_useslips:=_r.warehous_useslips;
      _row.warehous_usezones:=_r.warehous_usezones;
      _row.warehous_aislesize:=_r.warehous_aislesize;
      _row.warehous_racksize:=_r.warehous_racksize;
      _row.warehous_binsize:=_r.warehous_binsize;
      _row.warehous_binalpha:=_r.warehous_binalpha;
      _row.warehous_locationsize:=_r.warehous_locationsize;
      _row.warehous_locationalpha:=_r.warehous_locationalpha;
      _row.warehous_enforcearbl:=_r.warehous_enforcearbl;
      _row.warehous_default_accnt_id:=_r.warehous_default_accnt_id;
      _row.warehous_shipping_commission:=_r.warehous_shipping_commission;
      _row.warehous_cntct_id:=_r.warehous_cntct_id;
      _row.warehous_addr_id:=_r.warehous_addr_id;
      _row.warehous_taxzone_id:=_r.warehous_taxzone_id;
      _row.warehous_transit:=_r.warehous_transit;
      _row.warehous_shipform_id:=_r.warehous_shipform_id;
      _row.warehous_shipvia_id:=_r.warehous_shipvia_id;
      _row.warehous_shipcomments:=_r.warehous_shipcomments;
      _row.warehous_costcat_id:=_r.warehous_costcat_id;
      _row.warehous_sitetype_id:=_r.warehous_sitetype_id;
             
      RETURN NEXT _row;
    END LOOP;
  END IF;
  
  RETURN;
END;

Function: public.snoozemessage(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pMsgid ALIAS FOR $1;
  snooze INTERVAL := '10 minutes';

BEGIN

  UPDATE msg
  SET msg_scheduled=(msg_scheduled + snooze)
  WHERE (msg_id=pMsgid);

  RETURN TRUE;

END;

Function: public.spellamount(numeric)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN spellAmount($1, baseCurrId());
END;

Function: public.spellamount(numeric, integer)

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pN ALIAS FOR $1;
  pCurrId ALIAS FOR $2;
  _t text;
  _dollars text;
  _cents text;
  _l integer;
  _p integer;
  _words text;
  _word text;
  _hundreds char;
  _tens char;
  _ones char;
  _fractionalPartName text;
  _curr curr_symbol%ROWTYPE;
BEGIN

  _t := ltrim(to_char(pN, '999999999990D99'),' ');
  IF strpos(_t, '.') > 0 THEN
    _dollars := split_part(_t, '.', 1);
    _cents := split_part(_t, '.', 2);
  ELSIF strpos(_t, ',') > 0 THEN
    _dollars := split_part(_t, ',', 1);
    _cents := split_part(_t, ',', 2);
  END IF;

  _p := 0;
  _l := length(_dollars);

  _words := '';
  WHILE (_p < _l) LOOP
    IF((_l - _p - 2) < 1) THEN
      _hundreds := '0';
    ELSE
      _hundreds := substr(_dollars, _l - _p - 2, 1);
    END IF;
    IF((_l - _p - 1) < 1) THEN
      _tens := '0';
    ELSE
      _tens := substr(_dollars, _l - _p - 1, 1);
    END IF;
    IF((_l - _p) < 1) THEN
      _ones := '0';
    ELSE
      _ones := substr(_dollars, _l - _p, 1);
    END IF;

    IF(_hundreds != '0' OR _tens != '0' OR _ones != '0') THEN
      IF (_p = 3) THEN
        _words := 'thousand ' || _words;
      ELSIF (_p = 6) THEN
        _words := 'million ' || _words;
      ELSIF (_p = 9) THEN
        _words := 'billion ' || _words;
      END IF;

      _word := '';
      IF(_tens = '1') THEN
        IF(_ones = '0') THEN
          _word := 'ten';
        ELSIF(_ones = '1') THEN
          _word := 'eleven';
        ELSIF(_ones = '2') THEN
          _word := 'twelve';
        ELSIF(_ones = '3') THEN
          _word := 'thirteen';
        ELSIF(_ones = '4') THEN
          _word := 'fourteen';
        ELSIF(_ones = '5') THEN
          _word := 'fifteen';
        ELSIF(_ones = '6') THEN
          _word := 'sixteen';
        ELSIF(_ones = '7') THEN
          _word := 'seventeen';
        ELSIF(_ones = '8') THEN
          _word := 'eighteen';
        ELSIF(_ones = '9') THEN
          _word := 'nineteen';
        ELSE
          _word := 'ERROR';
        END IF;
      ELSE
        IF(_ones = '1') THEN
          _word := 'one';
        ELSIF(_ones = '2') THEN
          _word := 'two';
        ELSIF(_ones = '3') THEN
          _word := 'three';
        ELSIF(_ones = '4') THEN
          _word := 'four';
        ELSIF(_ones = '5') THEN
          _word := 'five';
        ELSIF(_ones = '6') THEN
          _word := 'six';
        ELSIF(_ones = '7') THEN
          _word := 'seven';
        ELSIF(_ones = '8') THEN
          _word := 'eight';
        ELSIF(_ones = '9') THEN
          _word := 'nine';
        ELSIF(_ones != '0') THEN
          _word := 'ERROR';
        END IF;

        if(_tens != '0') THEN
          _word := '-' || _word;
        END IF;

        IF(_tens = '2') THEN
          _word := 'twenty' || _word;
        ELSIF(_tens = '3') THEN
          _word := 'thirty' || _word;
        ELSIF(_tens = '4') THEN
          _word := 'forty' || _word;
        ELSIF(_tens = '5') THEN
          _word := 'fifty' || _word;
        ELSIF(_tens = '6') THEN
          _word := 'sixty' || _word;
        ELSIF(_tens = '7') THEN
          _word := 'seventy' || _word;
        ELSIF(_tens = '8') THEN
          _word := 'eighty' || _word;
        ELSIF(_tens = '9') THEN
          _word := 'ninety' || _word;
        ELSIF(_tens != '0' AND _tens != '1') THEN
          _word := 'ERROR' || _word;
        END IF;
      END IF;
      if(_word != '') THEN
        _words := _word || ' ' || _words;
      END IF;

      _word := '';
      IF(_hundreds = '1') THEN
        _word := 'one hundred';
      ELSIF(_hundreds = '2') THEN
        _word := 'two hundred';
      ELSIF(_hundreds = '3') THEN
        _word := 'three hundred';
      ELSIF(_hundreds = '4') THEN
        _word := 'four hundred';
      ELSIF(_hundreds = '5') THEN
        _word := 'five hundred';
      ELSIF(_hundreds = '6') THEN
        _word := 'six hundred';
      ELSIF(_hundreds = '7') THEN
        _word := 'seven hundred';
      ELSIF(_hundreds = '8') THEN
        _word := 'eight hundred';
      ELSIF(_hundreds = '9') THEN
        _word := 'nine hundred';
      ELSIF(_hundreds != '0') THEN
        _words := 'ERROR';
      END IF;
      if(_word != '') THEN
        _words := _word || ' ' || _words;
      END IF;
    END IF;

    _p := _p + 3;
  END LOOP;

  _words := rtrim(_words, ' ');
  IF(_words = '') THEN
    _words := 'zero';
  END IF;

  SELECT * INTO _curr
    FROM curr_symbol
    WHERE curr_id = pCurrId;

  IF(_words = 'one') AND TRIM(_curr.curr_name) ~ '.*s' THEN
    _word := rtrim(_curr.curr_name, ' s');
  ELSE
    _word := trim(_curr.curr_name);
  END IF;

  IF _curr.curr_abbr = 'USD' OR _curr.curr_abbr = 'CAD' THEN
      IF (_cents = '1') THEN
        _fractionalPartName = ' cent';
      ELSE
        _fractionalPartName = ' cents';
      END IF;
  ELSE
    _fractionalPartName = ' / 100 ';
  END IF;

  RETURN _words || ' ' || _word || ' and ' || _cents || _fractionalPartName;
END;

Function: public.splitreceipt(integer, numeric, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  precvid	ALIAS FOR $1;
  pqty   	ALIAS FOR $2;
  pfreight	ALIAS FOR $3;
  _check       	RECORD;
  _seq      	INTEGER;

BEGIN
  -- validate
  IF (COALESCE(pQty,0) <= 0) THEN
    RETURN -7;
  END IF;
  
  SELECT * INTO _check
  FROM recv
  WHERE (recv_id=precvid);

  IF (FOUND) THEN
    IF (_check.recv_order_type != 'PO') THEN
      RETURN -1;
    ELSIF ( NOT _check.recv_posted) THEN
      RETURN -2;
    ELSIF ( (_check.recv_invoiced)
         OR (_check.recv_vohead_id IS NOT NULL)
         OR (_check.recv_voitem_id IS NOT NULL) ) THEN
      RETURN -3;
    ELSIF (pqty >= _check.recv_qty) THEN
      RETURN -4;
    ELSIF (COALESCE(pfreight,0) > _check.recv_freight) THEN
      RETURN -5;
    END IF;
  ELSE
    RETURN -6;
  END IF;

  -- Create new receipt record
  _seq := nextval('recv_recv_id_seq');
  
  INSERT INTO recv
  SELECT _seq, recv_order_type,recv_order_number,
         recv_orderitem_id, recv_agent_username, recv_itemsite_id, recv_vend_id,
         recv_vend_item_number, recv_vend_item_descrip, recv_vend_uom,
         recv_purchcost, recv_purchcost_curr_id, recv_duedate, pqty, 
         recv_recvcost, recv_recvcost_curr_id, COALESCE(pfreight,0), recv_freight_curr_id, recv_date, 
         ROUND(recv_value/recv_qty * pqty, 2), TRUE, FALSE, NULL, NULL,
         recv_trans_usr_name, recv_notes, recv_gldistdate, precvid
  FROM recv
  WHERE (recv_id=precvid);

  --  Update qty and value of old record
  UPDATE recv SET
    recv_qty = recv_qty-pqty,
    recv_value = recv_value - ROUND(recv_value/recv_qty * pqty, 2),
    recv_freight = recv_freight - COALESCE(pfreight,0)
  WHERE (recv_id=precvid);

  RETURN _seq;
END;

Function: public.splitrecurrence(integer, text, timestamp with time zone)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pParentid     ALIAS FOR $1;
  pType         TEXT := UPPER($2);
  pDatetime     TIMESTAMP WITH TIME ZONE := COALESCE($3, CURRENT_TIMESTAMP);

  _count         INTEGER;
  _newrecurid    INTEGER;
  _newparentid   INTEGER;
  _newparentstmt TEXT;
  _rt            RECORD;
  _updchildstmt  TEXT;

BEGIN
  IF (pParentid IS NULL) THEN
    RETURN -11;
  END IF;

  SELECT * INTO _rt FROM recurtype WHERE (UPPER(recurtype_type)=pType);
  GET DIAGNOSTICS _count = ROW_COUNT;
  IF (_count <= 0) THEN
    RETURN -10;
  END IF;

  _newparentstmt := 'SELECT [table]_id FROM [fulltable]'
                 || ' WHERE (([table]_recurring_[table]_id=$1)'
                 || '    AND NOT ([done])'
                 || '    AND ([schedcol]>=''$2''))'
                 || ' ORDER BY [schedcol]'
                 || ' LIMIT 1;';
  _newparentstmt := REPLACE(_newparentstmt, '[fulltable]', _rt.recurtype_table);
  _newparentstmt := REPLACE(_newparentstmt, '[table]',
                            REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
  _newparentstmt := REPLACE(_newparentstmt, '[done]',  _rt.recurtype_donecheck);
  _newparentstmt := REPLACE(_newparentstmt, '[schedcol]', _rt.recurtype_schedcol);
  _updchildstmt := 'UPDATE [fulltable] SET [table]_recurring_[table]_id=$1'
                || ' WHERE (([table]_recurring_[table]_id=$2)'
                || '   AND NOT ([done])'
                || '   AND ([schedcol] > ''$3''));';
  _updchildstmt := REPLACE(_updchildstmt, '[fulltable]', _rt.recurtype_table);
  _updchildstmt := REPLACE(_updchildstmt, '[table]',
                           REGEXP_REPLACE(_rt.recurtype_table, E'.*\\.', ''));
  _updchildstmt := REPLACE(_updchildstmt, '[done]',  _rt.recurtype_donecheck);
  _updchildstmt := REPLACE(_updchildstmt, '[schedcol]', _rt.recurtype_schedcol);

  -- 8.4+: EXECUTE _newparentstmt INTO _newparentid USING pParentid, pDatetime;
  EXECUTE REPLACE(REPLACE(_newparentstmt, '$1', pParentid::TEXT),
                                          '$2', pDatetime::TEXT)
          INTO _newparentid;

  -- if nothing to split
  IF (_newparentid = pParentid OR _newparentid IS NULL) THEN
    SELECT recur_id INTO _newrecurid
      FROM recur
     WHERE ((recur_parent_id=pParentid)
        AND (recur_parent_type=pType));

  ELSE
    INSERT INTO recur (recur_parent_id, recur_parent_type, recur_period,
                       recur_freq,      recur_start,       recur_end,
                       recur_max,       recur_data
             ) SELECT _newparentid,     pType,             recur_period,
                      recur_freq,       pDatetime,         recur_end,
                      recur_max,        recur_data
                 FROM recur
                WHERE ((recur_parent_id=pParentid)
                   AND (recur_parent_type=pType))
      RETURNING recur_id INTO _newrecurid;

    UPDATE recur SET recur_end=pDatetime
    WHERE ((recur_parent_id=pParentid)
       AND (recur_parent_type=pType));

    -- 8.4+: EXECUTE _updchildstmt USING _newparentid, pParentid, pDatetime;
    EXECUTE REPLACE(REPLACE(REPLACE(_updchildstmt, '$1', _newparentid::TEXT),
                                                   '$2', pParentid::TEXT),
                                                   '$3', pDatetime::TEXT);
  END IF;

  RETURN _newrecurid;
END;

Function: public.startoftime()

Returns: date

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT DATE('1970-01-01') AS return;

Function: public.stdcost(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN stdCost($1, NULL);
END;

Function: public.stdcost(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pBomitemid ALIAS FOR $2;
  _cost NUMERIC;

BEGIN

  SELECT SUM(COALESCE(bomitemcost_stdcost, itemcost_stdcost)) INTO _cost
  FROM itemcost
    LEFT OUTER JOIN bomitemcost ON (bomitemcost_bomitem_id=pBomitemid AND bomitemcost_costelem_id=itemcost_costelem_id)
  WHERE (itemcost_item_id=pItemid);

  IF (_cost IS NULL) THEN
    RETURN 0;
  ELSE
    RETURN _cost;
  END IF;

END;

Function: public.sufficientinventorytoshipitem(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype    ALIAS FOR $1;
  porderitemid  ALIAS FOR $2;

BEGIN
  RETURN sufficientInventoryToShipItem(pordertype, porderitemid, NULL);
END;

Function: public.sufficientinventorytoshipitem(text, integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype		ALIAS FOR $1;
  porderitemid		ALIAS FOR $2;
  pqty                  ALIAS FOR $3;
  _returnVal		INTEGER;
  _isqtyavail		BOOLEAN;

BEGIN
  IF (porderitemid IS NULL) THEN
    RETURN -1;
  END IF;

  IF (pordertype = 'SO') THEN
    IF ( SELECT fetchMetricBool('EnableSOReservations') ) THEN
      IF (SELECT (itemsite_costmethod = 'J')
          FROM coitem JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
          WHERE (coitem_id=porderitemid)) THEN
        RETURN 0;
      END IF;
      SELECT (((COALESCE(pqty, roundQty(item_fractional,
		      noNeg(coitem_qtyord - coitem_qtyshipped +
			    coitem_qtyreturned - qtyAtShipping(pordertype, coitem_id)
			   ))) - coitem_qtyreserved) * coitem_qty_invuomratio
		      ) <= itemsite_qtyonhand)
              AND 
             (((COALESCE(pqty, roundQty(item_fractional,
		      noNeg(coitem_qtyord - coitem_qtyshipped +
			    coitem_qtyreturned - qtyAtShipping(pordertype, coitem_id)
			   ))) - coitem_qtyreserved) * coitem_qty_invuomratio
		      ) <= qtyunreserved(itemsite_id))
        INTO _isqtyavail
        FROM coitem, itemsite, item
       WHERE ((coitem_itemsite_id=itemsite_id) 
         AND (coitem_status <> 'X')
         AND  (NOT ((item_type IN ('R','J')) OR (itemsite_controlmethod = 'N'))) 
         AND (itemsite_item_id=item_id) 
         AND (coitem_id=porderitemid));
    ELSE
      SELECT (COALESCE(pqty, roundQty(item_fractional,
		                      noNeg(coitem_qtyord - coitem_qtyshipped +
			              coitem_qtyreturned - qtyAtShipping(pordertype, coitem_id) - coitem_qtyreserved
			              ) * coitem_qty_invuomratio
		      )
              ) <= itemsite_qtyonhand)
        INTO _isqtyavail
        FROM coitem, itemsite, item
       WHERE ((coitem_itemsite_id=itemsite_id) 
         AND (coitem_status <> 'X')
         AND  (NOT ((item_type IN ('R','J')) OR (itemsite_controlmethod = 'N'))) 
         AND (itemsite_item_id=item_id) 
         AND (coitem_id=porderitemid));
    END IF;
  ELSEIF (pordertype = 'TO') THEN
    SELECT (COALESCE(pqty, roundQty(item_fractional,
		                    noNeg(toitem_qty_ordered - toitem_qty_shipped - 
			            qtyAtShipping(pordertype, toitem_id)
		                    )
		    )
           ) <= itemsite_qtyonhand) INTO _isqtyavail  
      FROM toitem, tohead, itemsite, item
     WHERE ((toitem_tohead_id=tohead_id)
       AND  (tohead_src_warehous_id=itemsite_warehous_id) 
       AND  (toitem_item_id=itemsite_item_id) 
       AND  (itemsite_warehous_id=tohead_src_warehous_id) 
       AND  (itemsite_item_id=item_id) 
       AND  (toitem_status <> 'X')
         AND  (NOT ((item_type IN ('R','J')) OR (itemsite_controlmethod = 'N'))) 
       AND  (toitem_id=porderitemid));
  ELSE
    RETURN -11;
  END IF;

  IF (NOT _isqtyavail) THEN
    RETURN -2;
  END IF;

  IF (pordertype = 'SO') THEN
    SELECT (COALESCE((SELECT SUM(itemloc_qty) 
			FROM itemloc 
		       WHERE (itemloc_itemsite_id=itemsite_id)), 0.0) >= roundQty(item_fractional, 
			      COALESCE(pQty, noNeg( coitem_qtyord - coitem_qtyshipped + coitem_qtyreturned - 
			      qtyAtShipping(pordertype, coitem_id) )) * coitem_qty_invuomratio
			     )) INTO _isqtyavail 
      FROM coitem, itemsite, item
     WHERE ((coitem_itemsite_id=itemsite_id) 
       AND (itemsite_item_id=item_id) 
       AND (NOT ((item_type ='R') OR (itemsite_controlmethod = 'N'))) 
       AND ((itemsite_controlmethod IN ('L', 'S')) OR (itemsite_loccntrl)) 
       AND (coitem_id=porderitemid)); 

  ELSEIF (pordertype = 'TO') THEN
    SELECT (COALESCE((SELECT SUM(itemloc_qty) 
			FROM itemloc 
		       WHERE (itemloc_itemsite_id=itemsite_id)), 0.0) >= roundQty(item_fractional, 
			      noNeg( toitem_qty_ordered - toitem_qty_shipped - 
			      qtyAtShipping(pordertype, toitem_id) )
			     )) INTO _isqtyavail 
      FROM toitem, tohead, itemsite, item
     WHERE ((toitem_tohead_id=tohead_id)
       AND  (tohead_src_warehous_id=itemsite_warehous_id) 
       AND  (toitem_item_id=itemsite_item_id) 
       AND  (itemsite_item_id=item_id) 
       AND  (toitem_status <> 'X')
       AND  (NOT ((item_type ='R') OR (itemsite_costmethod = 'J') OR (itemsite_controlmethod = 'N'))) 
       AND  ((itemsite_controlmethod IN ('L', 'S')) OR (itemsite_loccntrl)) 
       AND  (toitem_id=porderitemid)); 
  END IF;
  
  IF (NOT _isqtyavail) THEN
    RETURN -3;
  END IF;

  RETURN 0;
END;

Function: public.sufficientinventorytoshiporder(text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  porderid	ALIAS FOR $2;
  _s		RECORD;
  _returnVal	INTEGER := 0;

BEGIN
  IF (pordertype = 'SO') THEN
    FOR _s IN SELECT coitem_id
	        FROM coitem
	         JOIN itemsite ON (coitem_itemsite_id=itemsite_id)
	       WHERE((coitem_cohead_id=porderid) 
	        AND (itemsite_costmethod != 'J')) LOOP
      _returnVal := sufficientInventoryToShipItem(pordertype, _s.coitem_id);
      EXIT WHEN (_returnVal < 0);
    END LOOP;
  ELSEIF (pordertype = 'TO') THEN
    FOR _s IN SELECT toitem_id
	        FROM toitem
	       WHERE(toitem_tohead_id=porderid) LOOP
      _returnVal := sufficientInventoryToShipItem(pordertype, _s.toitem_id);
      EXIT WHEN (_returnVal < 0);
    END LOOP;
  END IF;

  RETURN _returnVal;
END;

Function: public.summarizedbom(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  _revid INTEGER;

BEGIN

  SELECT getActiveRevId('BOM',pItemid) INTO _revid;
  
  RETURN summarizedBOM(pItemid, _revid);

END;

Function: public.summarizedbom(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  _bomworkid INTEGER;
  _indexid INTEGER;
  _r RECORD;

BEGIN

--  Check on the temporary workspace
--  PERFORM maintainBOMWorkspace();

--  Grab a new index for this bomwork set
  SELECT NEXTVAL('misc_index_seq') INTO _indexid;

--  Step through all of the components of the passed pItemid
  FOR _r IN SELECT bomitem.*,
                   item_id,
                   itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL,
                                bomitem_qtyfxd) AS qtyfxd,
                   itemuomtouom(bomitem_item_id, bomitem_uom_id, NULL,
                                bomitem_qtyper) AS qtyper,
                   stdcost(item_id, bomitem_id) AS standardcost,
                   actcost(item_id, bomitem_id) AS actualcost
  FROM bomitem(pItemid, pRevisionid), item
  WHERE (bomitem_item_id=item_id) LOOP

--  Insert the component and bomitem parameters
    SELECT NEXTVAL('bomwork_bomwork_id_seq') INTO _bomworkid;
    INSERT INTO bomwork
    ( bomwork_id, bomwork_set_id, bomwork_parent_id, bomwork_level,
      bomwork_parent_seqnumber, bomwork_seqnumber,
      bomwork_item_id, bomwork_createwo, bomwork_qtyreq,
      bomwork_qtyfxd, bomwork_qtyper, bomwork_scrap, bomwork_issuemethod,
      bomwork_effective, bomwork_expires,
      bomwork_stdunitcost, bomwork_actunitcost )
    VALUES
    ( _bomworkid, _indexid, -1, 1,
      0, _r.bomitem_seqnumber,
      _r.item_id, _r.bomitem_createwo, (_r.qtyfxd + _r.qtyper),
      _r.qtyfxd, _r.qtyper, _r.bomitem_scrap, _r.bomitem_issuemethod,
      _r.bomitem_effective, _r.bomitem_expires,
      _r.standardcost, _r.actualcost,
      _r.bomitem_char_id, _r.bomitem_value, _r.bomitem_notes, _r.bomitem_ref,
      _r.bomitem_id, _r.bomitem_ecn );

--  Explode the components of the current component
    PERFORM explodeBOM(_r.item_id, _bomworkid, 1);

  END LOOP;

--  Return a key to the result
  RETURN _indexid;

END;

Function: public.summarizedbom(integer, integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pExpired ALIAS FOR $2;
  pFuture ALIAS FOR $3;
  _revid INTEGER;

BEGIN

  SELECT getActiveRevId('BOM',pItemid) INTO _revid;
  
  RETURN summarizedBOM(pItemid, _revid, pExpired, pFuture);

END;

Function: public.summarizedbom(integer, integer, integer, integer)

Returns: SET OF bomdata

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pRevisionid ALIAS FOR $2;
  pExpiredDays  INTEGER := COALESCE($3, 0);
  pFutureDays   INTEGER := COALESCE($4, 0);
  _row bomdata%ROWTYPE;
  _bomworksetid INTEGER;
  _x RECORD;
  _check CHAR(1);
  _inactive BOOLEAN := FALSE;
  _batchsize NUMERIC;

BEGIN

  IF (pRevisionid != -1) THEN
    --Is this a deactivated revision?
    SELECT rev_status INTO _check
    FROM rev
    WHERE ((rev_id=pRevisionid)
    AND (rev_status='I'));
    IF (FOUND) THEN
      _inactive := TRUE;
    END IF;
  END IF;
 
  -- Get the batch quantity
  SELECT COALESCE( (
    SELECT bomhead_batchsize
    FROM bomhead
    WHERE ((bomhead_item_id=pItemId)
    AND (bomhead_rev_id=pRevisionid))),1) INTO _batchsize;
 
  IF NOT (_inactive) THEN

    --We can explode this out based on current data
    SELECT indentedBOM(pItemid, pRevisionid) INTO _bomworksetid;  

    FOR _x IN
       SELECT item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               SUM(bomwork_qtyreq * (1 + bomwork_scrap)) AS qtyreq,
               SUM(bomwork_qtyfxd * (1 + bomwork_scrap)) AS qtyfxd,
               SUM(bomwork_qtyper * (1 + bomwork_scrap)) AS qtyper,
       MAX(bomwork_actunitcost) AS actunitcost,
       MAX(bomwork_stdunitcost) AS stdunitcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         SUM(bomwork_actunitcost * (bomwork_qtyfxd/_batchsize + bomwork_qtyper * (1 + bomwork_scrap)))
       ELSE 0 END AS actextendedcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         SUM(bomwork_stdunitcost * (bomwork_qtyfxd/_batchsize + bomwork_qtyper * (1 + bomwork_scrap)))
       ELSE 0 END AS stdextendedcost,
       bomwork_effective,
       bomwork_expires,
       bomwork_effective > CURRENT_DATE AS future,
       bomwork_expires  <= CURRENT_DATE AS expired
       FROM ( SELECT item_number, item_type, uom_name,
                     item_descrip1, item_descrip2,
                     bomwork_qtyreq, bomwork_qtyfxd,
                     bomwork_qtyper, bomwork_scrap,
                     bomwork_actunitcost, bomwork_stdunitcost,
                     CASE WHEN (bomwork_effective > CURRENT_DATE) THEN (CURRENT_DATE + 1)
                          ELSE CURRENT_DATE END AS bomwork_effective,
                     CASE WHEN (bomwork_expires <= CURRENT_DATE) THEN (CURRENT_DATE - 1)
                          ELSE (CURRENT_DATE + 1) END AS bomwork_expires
                     FROM bomwork, item, uom 
                     WHERE ( (bomwork_item_id=item_id)
                       AND (item_inv_uom_id=uom_id)
                       AND (bomwork_set_id=_bomworksetid) )
                       AND (bomwork_expires > (CURRENT_DATE - pExpiredDays))
                       AND (bomwork_effective <= (CURRENT_DATE + pFutureDays)) ) AS data
       GROUP BY item_number, uom_name, item_type,
                item_descrip1, item_descrip2,
                bomwork_effective, bomwork_expires
       ORDER BY item_number
    LOOP
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_qtyreq := _x.qtyreq;
        _row.bomdata_qtyfxd := _x.qtyfxd;
        _row.bomdata_qtyper := _x.qtyper;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        _row.bomdata_effective := _x.bomwork_effective;
        _row.bomdata_expires := _x.bomwork_expires;
        _row.bomdata_future := _x.future;
        _row.bomdata_expired := _x.expired;
        RETURN NEXT _row;
    END LOOP;
    
    PERFORM deleteBOMWorkset(_bomworksetid);

  ELSE
   
-- Use historical snapshot for inactive revisions
    FOR _x IN
       SELECT item_number, uom_name,
               item_descrip1, item_descrip2,
               (item_descrip1 || ' ' || item_descrip2) AS itemdescription,
               SUM(bomhist_qtyreq * (1 + bomhist_scrap)) AS qtyreq,
               SUM(bomhist_qtyfxd * (1 + bomhist_scrap)) AS qtyfxd,
               SUM(bomhist_qtyper * (1 + bomhist_scrap)) AS qtyper,
       MAX(bomhist_actunitcost) AS actunitcost,
       MAX(bomhist_stdunitcost) AS stdunitcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         MAX(bomhist_actunitcost) * SUM((bomhist_qtyfxd/_batchsize + bomhist_qtyper) * (1 + bomhist_scrap))
       ELSE 0 END AS actextendedcost,
       CASE WHEN item_type NOT IN ('R','T') THEN
         MAX(bomhist_stdunitcost) * SUM((bomhist_qtyfxd/_batchsize + bomhist_qtyper) * (1 + bomhist_scrap)) 
       ELSE 0 END AS stdextendedcost
       FROM bomhist, item, uom 
       WHERE ( (bomhist_item_id=item_id)
       AND (item_inv_uom_id=uom_id)
       AND (bomhist_rev_id=pRevisionid) )
       AND (bomhist_expires > (CURRENT_DATE - pExpiredDays))
       AND (bomhist_effective <= (CURRENT_DATE + pFutureDays))
       GROUP BY item_number, uom_name, item_type,
                item_descrip1, item_descrip2
       ORDER BY item_number
    LOOP
        _row.bomdata_item_number := _x.item_number;
        _row.bomdata_uom_name := _x.uom_name;
        _row.bomdata_item_descrip1 := _x.item_descrip1;
        _row.bomdata_item_descrip2 := _x.item_descrip2;
        _row.bomdata_itemdescription := _x.itemdescription;
        _row.bomdata_qtyreq := _x.qtyreq;
        _row.bomdata_qtyfxd := _x.qtyfxd;
        _row.bomdata_qtyper := _x.qtyper;
        _row.bomdata_actunitcost := _x.actunitcost;
        _row.bomdata_stdunitcost := _x.stdunitcost;
        _row.bomdata_actextendedcost := _x.actextendedcost;
        _row.bomdata_stdextendedcost := _x.stdextendedcost;
        RETURN NEXT _row;
    END LOOP;

  END IF;

  RETURN;

END;

Function: public.summarizetransactions(integer, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _startDate DATE;
  _endDate DATE;
  _invhist RECORD;
  _itemuom TEXT;
  _transCounter INTEGER;
  _itemlocSeries INTEGER;

BEGIN

--  Cache the uom_name
  SELECT uom_name INTO _itemuom
  FROM itemsite, item, uom
  WHERE ((itemsite_item_id=item_id)
    AND (item_inv_uom_id=uom_id)
    AND (itemsite_id=pItemsiteid));

--  Can't summarize into the future...
  IF (pEndDate > CURRENT_DATE) THEN
    _endDate := CURRENT_DATE;
  ELSE
    _endDate := pEndDate;
  END IF;

--  Verify date bounds
  IF (pStartDate > pEndDate) THEN
    _startDate := pEndDate;
  ELSE
    _startDate := pStartDate;
  END IF;

--  Verify that history is not referenced elsewhere
  SELECT invhist_id INTO _transCounter
  FROM invhist JOIN womatlpost ON (womatlpost_invhist_id=invhist_id)
  WHERE ((invhist_itemsite_id=pItemsiteid)
    AND (invhist_transdate::DATE BETWEEN _startDate AND _endDate))
  LIMIT 1;
  IF (FOUND) THEN
    RETURN 0;
  END IF;

  SELECT invhist_id INTO _transCounter
  FROM invhist JOIN shipitem ON (shipitem_invhist_id=invhist_id)
  WHERE ((invhist_itemsite_id=pItemsiteid)
    AND (invhist_transdate::DATE BETWEEN _startDate AND _endDate))
  LIMIT 1;
  IF (FOUND) THEN
    RETURN 0;
  END IF;

  _transCounter := 0;
  _itemlocSeries := NEXTVAL('itemloc_series_seq');

  FOR _invhist IN SELECT invhist_transtype, invhist_costmethod, SUM(invhist_invqty) AS qty
                  FROM invhist
                  WHERE ((invhist_itemsite_id=pItemsiteid)
                   AND (invhist_transdate::DATE BETWEEN _startDate AND _endDate))
                  GROUP BY invhist_transtype, invhist_costmethod LOOP

    DELETE FROM invhist
    WHERE ((invhist_transdate::DATE BETWEEN _startDate AND _endDate)
     AND (invhist_transtype=_invhist.invhist_transtype)
     AND (invhist_itemsite_id=pItemsiteid));

    INSERT INTO invhist
    ( invhist_itemsite_id, invhist_transdate, invhist_transtype,
      invhist_invqty, invhist_qoh_before, invhist_qoh_after,
      invhist_invuom, invhist_user, invhist_ordnumber,
      invhist_costmethod, invhist_value_before, invhist_value_after,
      invhist_series )
    VALUES
    ( pItemsiteid, _endDate, _invhist.invhist_transtype,
      _invhist.qty, 0, 0,
      _itemuom, getEffectiveXtUser(), 'Summary',
      _invhist.invhist_costmethod, 0, 0,
      _itemlocSeries );

    _transCounter := (_transCounter + 1);

  END LOOP;

  RETURN _transCounter;

END;

Function: public.summdemand(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(wo_qtyord - wo_qtyrcv) INTO _value
  FROM wo
  WHERE ( (wo_itemsite_id=pItemsiteid)
   AND (wo_status IN ('R', 'I'))
   AND (wo_startdate::DATE BETWEEN pStartDate AND pEndDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summdemand(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summDemand(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summprod(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(invhist_invqty) INTO _value
  FROM invhist
  WHERE ( (invhist_itemsite_id=pItemsiteid)
   AND (invhist_transtype IN ('RM', 'RB'))
   AND (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summprod(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summProd(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtransa(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(invhist_invqty) INTO _value
  FROM invhist
  WHERE ((invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('AD', 'CC'))
   AND (invhist_itemsite_id=pItemsiteid));

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtransa(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransA(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtransc(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDAte ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(invhist_invqty) INTO _value
  FROM invhist
  WHERE ((invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('SI'))
   AND (invhist_itemsite_id=pItemsiteid));

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtransc(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransC(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtransi(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(invhist_invqty) INTO _value
  FROM invhist
  WHERE ((invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('IM', 'IC'))
   AND (invhist_itemsite_id=pItemsiteid));

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtransi(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransI(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtransr(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM(invhist_invqty) INTO _value
  FROM invhist
  WHERE ((invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('RM', 'RP', 'RX'))
   AND (invhist_itemsite_id=pItemsiteid) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtransr(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransR(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtranss(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM( CASE WHEN (invhist_transtype = 'RS') THEN (invhist_invqty * -1)
                   ELSE (invhist_invqty)
              END ) INTO _value
  FROM invhist
  WHERE ( (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('SC', 'SH', 'SV', 'RS'))
   AND (invhist_itemsite_id=pItemsiteid) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtranss(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransS(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.summtranst(integer, date, date)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pStartDate ALIAS FOR $2;
  pEndDate ALIAS FOR $3;
  _value NUMERIC;

BEGIN

  SELECT SUM( CASE WHEN (invhist_transtype = 'TS') THEN (invhist_invqty * -1)
                   ELSE (invhist_invqty)
              END ) INTO _value
  FROM invhist
  WHERE ( (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
   AND (invhist_transtype IN ('TS', 'TR', 'TW'))
   AND (invhist_itemsite_id=pItemsiteid) );

  IF (_value IS NULL) THEN
    _value := 0;
  END IF;

  RETURN _value;

END;

Function: public.summtranst(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pCalitemid ALIAS FOR $2;
  _value NUMERIC;

BEGIN

  SELECT summTransT(pItemsiteid, findPeriodStart(pCalitemid), findPeriodEnd(pCalitemid)) INTO _value;

  RETURN _value;

END;

Function: public.taxassignments(integer, integer)

Returns: SET OF taxassign

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTaxZoneId ALIAS FOR $1;
  pTaxTypeId ALIAS FOR $2;
  _row taxassign%ROWTYPE;
  _qry text;
  _x RECORD;
  _y RECORD;
  _z RECORD;

BEGIN
  _qry = 'SELECT DISTINCT COALESCE(taxass_taxzone_id, -1) AS taxass_taxzone_id, COALESCE(taxass_taxtype_id, -1) AS taxass_taxtype_id, ';
  _qry = _qry || 'taxzone_code, taxtype_name FROM taxass LEFT OUTER JOIN taxzone ON (taxass_taxzone_id=taxzone_id) ';
  _qry = _qry || 'LEFT OUTER JOIN taxtype ON (taxass_taxtype_id=taxtype_id) ';

  IF ((pTaxZoneId > 0) OR (pTaxTypeId > 0)) THEN
    _qry := _qry || ' WHERE ';
    IF (pTaxZoneId > 0) THEN
      _qry := _qry || ' (taxass_taxzone_id = ' || pTaxZoneId ||')';
      IF (pTaxTypeId > 0) THEN
        _qry := _qry || ' AND ';
      END IF;
    END IF;
    IF (pTaxTypeId > 0) THEN
      _qry := _qry || ' (taxass_taxtype_id = ' || pTaxTypeId || ')';
    END IF;
  END IF;

  --This first query gets all the distinct tax zone and type groupings as if it were its own table.
  --This allows us to have a level 0 record as pictured in Tax Assignments window that code assignements will
  --Subordinate to.
  FOR _x IN  EXECUTE _qry
  LOOP
    --Map values to _row here
    _row.taxassign_taxzone_id = _x.taxass_taxzone_id;
    _row.taxassign_taxtype_id = _x.taxass_taxtype_id;
    _row.taxassign_level = 0;
    _row.taxassign_zone_code = _x.taxzone_code;
    _row.taxassign_type_descrip = _x.taxtype_name;
    _row.taxassign_taxclass_code = '';
    _row.taxassign_taxclass_sequence = NULL;
    RETURN NEXT _row; --so we get a level tax zone/type 0 record.
  
    -- Now get all the tax code assignments that belong to this Zone and Type pair
    FOR _y IN
      SELECT taxass_id, COALESCE(taxzone_id, -1) AS taxzone_id, tax_id,
      tax_code, tax_descrip, COALESCE(taxtype_id, -1) AS taxtype_id, taxzone_code, 
      taxtype_descrip, taxclass_code, 
      COALESCE(taxclass_sequence, 0) AS taxclass_sequence
      FROM taxass JOIN tax 
         LEFT OUTER JOIN taxclass ON (tax_taxclass_id = taxclass_id)
      ON (taxass_tax_id = tax_id)
      LEFT OUTER JOIN taxzone ON (taxass_taxzone_id = taxzone_id)
      LEFT OUTER JOIN taxtype ON (taxass_taxtype_id = taxtype_id)
      WHERE COALESCE(taxass_taxzone_id, -1) = _x.taxass_taxzone_id
      AND   COALESCE(taxass_taxtype_id, -1) = _x.taxass_taxtype_id
    LOOP
      --Map results to _row
      _row.taxassign_taxzone_id = _y.taxzone_id;
      _row.taxassign_taxtype_id = _y.taxtype_id;
      _row.taxassign_level = 1;
      _row.taxassign_zone_code = _y.tax_code;
      _row.taxassign_type_descrip = _y.tax_descrip;
      _row.taxassign_taxclass_code = _y.taxclass_code;
      _row.taxassign_taxclass_sequence = _y.taxclass_sequence;
      RETURN NEXT _row; --to get code detail record;
      
      FOR _z IN SELECT * FROM getsubtax(_y.tax_id, 1) --a new recursive function described above
      LOOP
        --Map results to _row
        _row.taxassign_taxzone_id = _y.taxzone_id;
        _row.taxassign_taxtype_id = _y.taxtype_id;
        _row.taxassign_level = _z.subtax_taxcode_level;
        _row.taxassign_zone_code = _z.subtax_taxcode_code;
        _row.taxassign_type_descrip = _z.subtax_taxcode_descrip;
        _row.taxassign_taxclass_code = _y.taxclass_code;
        _row.taxassign_taxclass_sequence = _y.taxclass_sequence;
        RETURN NEXT _row;
      END  LOOP;

    END LOOP;

  END LOOP;

END;

Function: public.thawaccountingperiod(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pPeriodid ALIAS FOR $1;
  _r RECORD;

BEGIN

--  Check to make sure that the period is frozen
  IF ( ( SELECT (NOT period_freeze)
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -2;
  END IF;

--  Check to make sure that the period is not closed
  IF ( ( SELECT (period_closed)
         FROM period
         WHERE (period_id=pPeriodid) ) ) THEN
    RETURN -1;
  END IF;

--  Reset the period_freeze flag
  UPDATE period
  SET period_freeze=FALSE
  WHERE (period_id=pPeriodid);

--  Post any unposted G/L Transactions into the period
  FOR _r IN SELECT DISTINCT gltrans_sequence
            FROM gltrans, accnt, period
            WHERE ( (gltrans_accnt_id=accnt_id)
             AND (NOT gltrans_posted)
             AND (gltrans_date BETWEEN period_start AND period_end)
             AND (period_id=pPeriodid) ) LOOP
    PERFORM postIntoTrialBalance(_r.gltrans_sequence);
  END LOOP;

  RETURN pPeriodid;

END;

Function: public.thawitemsite(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _qoh            NUMERIC := 0;
  _netable_qoh    NUMERIC := 0;
  _nonnetable_qoh NUMERIC := 0;
  _value          NUMERIC := 0;
  _itemlocid INTEGER;
  _itemloc RECORD;
  _invhist RECORD;
  _coarse RECORD;
  _fine RECORD;

BEGIN

  IF ( SELECT itemsite_freeze
       FROM itemsite
       WHERE (itemsite_id=pItemsiteid) ) THEN

    SELECT invhist_id INTO _invhist
    FROM invhist
    WHERE ( (invhist_itemsite_id=pItemsiteid)
     AND (NOT invhist_posted) )
    LIMIT 1;
    IF (NOT FOUND) THEN
      UPDATE itemsite
      SET itemsite_freeze=FALSE
      WHERE (itemsite_id=pItemsiteid);
   END IF;

--  Run through any invdetail if this itemsite is still MLC and/or Lot/Serial
    IF ( SELECT ( (itemsite_loccntrl) OR
                  (itemsite_controlmethod IN ('L', 'S')) )
         FROM itemsite
         WHERE (itemsite_id=pItemsiteid) ) THEN

--  Grab all of the itemsite/location/lot/serial combinations
--  that have unposted detail
      FOR _coarse IN SELECT DISTINCT invdetail_location_id, invdetail_ls_id,
                                     invdetail_expiration, invdetail_warrpurc
                     FROM invhist, invdetail
                     WHERE ( (invdetail_invhist_id=invhist_id)
                      AND (NOT invhist_posted)
                      AND (invhist_itemsite_id=pItemsiteid) )
                     ORDER BY invdetail_location_id, invdetail_ls_id LOOP

--  Cache the initial qty of the itemloc specified by the
--  itemsite/location/lot/serial
        SELECT itemloc_id, itemloc_qty, COALESCE(location_netable, TRUE) AS location_netable
        INTO _itemloc
        FROM itemloc LEFT OUTER JOIN location ON (location_id=itemloc_location_id)
        WHERE ( (itemloc_itemsite_id=pItemsiteid)
         AND (itemloc_location_id=_coarse.invdetail_location_id)
         AND (COALESCE(itemloc_ls_id,-1)=COALESCE(_coarse.invdetail_ls_id,-1))
         AND (COALESCE(itemloc_expiration,endOfTime())=COALESCE(_coarse.invdetail_expiration,endOfTime()))
         AND (COALESCE(itemloc_warrpurc,endOfTime())=COALESCE(_coarse.invdetail_warrpurc,endOfTime())) );

--  If the itemloc in question cannot be found, create it
        IF (NOT FOUND) THEN
          SELECT NEXTVAL('itemloc_itemloc_id_seq') INTO _itemlocid;
          INSERT INTO itemloc
          ( itemloc_id, itemloc_itemsite_id,
            itemloc_location_id, itemloc_ls_id,
            itemloc_qty, itemloc_expiration )
          VALUES
          ( _itemlocid, pItemsiteid,
            _coarse.invdetail_location_id, _coarse.invdetail_ls_id,
            0, endOfTime() );

        _qoh := 0.0;
        _netable_qoh := 0.0;
        _nonnetable_qoh := 0.0;

        ELSE
          _itemlocid := _itemloc.itemloc_id;
          _qoh := _itemloc.itemloc_qty;
          IF (_itemloc.location_netable) THEN
            _netable_qoh := _itemloc.itemloc_qty;
          ELSE
            _nonnetable_qoh := _itemloc.itemloc_qty;
          END IF;
        END IF;

--  Now step through each unposted invdetail record for a given
--  itemsite/location/lot/serial
        FOR _fine IN SELECT invdetail_id, invdetail_qty
                     FROM invhist, invdetail
                     WHERE ( (invdetail_invhist_id=invhist_id)
                      AND (NOT invhist_posted)
                      AND (invhist_itemsite_id=pItemsiteid)
                      AND (invdetail_location_id=_coarse.invdetail_location_id)
                      AND (COALESCE(invdetail_ls_id,-1)=COALESCE(_coarse.invdetail_ls_id,-1))
                      AND (COALESCE(invdetail_expiration,endOfTime())=COALESCE(_coarse.invdetail_expiration,endOfTime()))
                      AND (COALESCE(invdetail_warrpurc,endOfTime())=COALESCE(_coarse.invdetail_warrpurc,endOfTime())) )
                     ORDER BY invhist_transdate LOOP

--  Update the running qoh fields in the detail record
          UPDATE invdetail
          SET invdetail_qty_before = _qoh,
              invdetail_qty_after = (_qoh + invdetail_qty)
          WHERE (invdetail_id=_fine.invdetail_id);

--  Update the running qoh
          _qoh = (_qoh + _fine.invdetail_qty);
          IF (_itemloc.location_netable) THEN
            _netable_qoh := (_netable_qoh + _fine.invdetail_qty);
          ELSE
            _nonnetable_qoh := (_nonnetable_qoh + _fine.invdetail_qty);
          END IF;

        END LOOP;

--  If the running qoh end up at 0, delete the itemloc in question
        IF (_qoh = 0) THEN
          DELETE FROM itemloc
          WHERE (itemloc_id=_itemlocid);

--  Otherwise, update the itemloc in question with the resultant qty
        ELSE
          UPDATE itemloc
          SET itemloc_qty=_qoh
          WHERE (itemloc_id=_itemlocid);
        END IF;

      END LOOP;

    END IF; 

--  Cache the inital qoh of the itemsite
    SELECT itemsite_qtyonhand, itemsite_value INTO _qoh, _value
    FROM itemsite
    WHERE (itemsite_id=pItemsiteid);

--  We have to un-freeze the itemsite before update-ing its QOH
--  so that that itemsite trigger won't block the QOH update.
--  Also so the invhist trigger won't block the posted update.

    UPDATE itemsite
    SET itemsite_freeze=FALSE
    WHERE (itemsite_id=pItemsiteid);

    FOR _invhist IN SELECT invhist_id,
                           invhist_qoh_before, invhist_qoh_after,
                           invhist_value_before, invhist_value_after
                      FROM invhist
                     WHERE((invhist_itemsite_id=pItemsiteid)
                       AND (NOT invhist_posted))
                     ORDER BY invhist_transdate LOOP

      UPDATE invhist
      SET invhist_qoh_before = _qoh,
          invhist_qoh_after = ( _qoh +
                                _invhist.invhist_qoh_after -
                                _invhist.invhist_qoh_before ),
          invhist_value_before = _value,
          invhist_value_after = ( _value +
                                  _invhist.invhist_value_after -
                                  _invhist.invhist_value_before ),
          invhist_posted = TRUE
      WHERE (invhist_id=_invhist.invhist_id);

      _qoh := (_qoh + (_invhist.invhist_qoh_after - _invhist.invhist_qoh_before));
      _value := (_value + (_invhist.invhist_value_after - _invhist.invhist_value_before));

    END LOOP;

-- _qoh can be used for the netable qoh because of the negative NN transactions
    UPDATE itemsite
       SET itemsite_qtyonhand = _qoh,
           itemsite_nnqoh = _nonnetable_qoh,
           itemsite_value = CASE WHEN ((itemsite_costmethod='A') AND (_value < 0.0)) THEN 0.0
                                 ELSE _value END
     WHERE(itemsite_id=pItemsiteid);

  END IF;

  RETURN pItemsiteid;

END;

Function: public.todoitem()

Returns: SET OF todoitem

Language: PLPGSQL

A table function that returns To Do Items results according to privilege settings.

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _row todoitem%ROWTYPE;
  _priv TEXT;
  _grant BOOLEAN;

BEGIN
  -- This query will give us the most permissive privilege the user has been granted
  SELECT privilege, granted INTO _priv, _grant
  FROM privgranted 
  WHERE privilege IN ('MaintainAllToDoItems','ViewAllToDoItems','MaintainPersonalToDoItems','ViewPersonalToDoItems')
  ORDER BY granted DESC, sequence
  LIMIT 1;

  -- If have an 'All' privilege return all results
  IF (_priv ~ 'All' AND _grant) THEN
    FOR _row IN 
      SELECT * FROM todoitem
    LOOP
      RETURN NEXT _row;
    END LOOP;
  -- Otherwise if have any other grant, must be personal privilege.
  ELSIF (_grant) THEN
    FOR _row IN 
      SELECT * FROM todoitem 
      WHERE getEffectiveXtUser() IN (todoitem_owner_username, todoitem_username)
    LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;

END;

Function: public.todoitemmove(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoItemId ALIAS FOR $1;
  pHowFar     ALIAS FOR $2;   -- -1 moves toward front of list, +1 toward back
  _howFar     INTEGER := pHowFar;
  _username   TEXT;
  _currseq    INTEGER;
BEGIN
  SELECT todoitem_username, todoitem_seq INTO _username, _currseq
  FROM todoitem
  WHERE todoitem_id = ptodoItemId;

  IF NOT FOUND THEN
    RETURN -1;
  END IF;

  IF (_currseq + pHowFar <= 0) THEN
    _howFar = 1 - _currseq;   -- move to beginning
  END IF;

  UPDATE todoitem
  SET todoitem_seq=todoitem_seq - _howFar
  WHERE todoitem_seq >= _currseq + _howFar
    AND todoitem_id != ptodoItemId
    AND todoitem_username = _username
    AND todoitem_status != 'C';

  UPDATE todoitem
  SET todoitem_seq=_currseq + _howFar
  WHERE todoitem_id = ptodoItemId;

  RETURN 0;
END;

Function: public.todoitemmovedown(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoItemId ALIAS FOR $1;
BEGIN
  RETURN todoItemMove(ptodoItemId, 1);        -- move toward end of list
END;

Function: public.todoitemmoveup(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoItemId ALIAS FOR $1;
BEGIN
  RETURN todoItemMove(ptodoItemId, -1);       -- move toward front of list
END;

Function: public.togglebankreccleared(integer, text, integer)

Returns: boolean

Language: PLPGSQL

DECLARE
  pBankrecid ALIAS FOR $1;
  pSource    ALIAS FOR $2;
  pSourceid  ALIAS FOR $3;
  _cleared BOOLEAN;
  _r RECORD;

BEGIN

  SELECT bankrecitem_id, bankrecitem_cleared INTO _r
    FROM bankrecitem
   WHERE ( (bankrecitem_bankrec_id=pBankrecid)
     AND   (bankrecitem_source=pSource)
     AND   (bankrecitem_source_id=pSourceid) );
  IF ( NOT FOUND ) THEN
    _cleared := TRUE;
    INSERT INTO bankrecitem
    (bankrecitem_bankrec_id, bankrecitem_source,
     bankrecitem_source_id, bankrecitem_cleared)
    VALUES
    (pBankrecid, pSource, pSourceid, _cleared);
  ELSE
    _cleared := (NOT _r.bankrecitem_cleared);
    UPDATE bankrecitem
       SET bankrecitem_cleared=_cleared
     WHERE (bankrecitem_id=_r.bankrecitem_id);
  END IF;

  RETURN _cleared;
END;

Function: public.togglebankreccleared(integer, text, integer, numeric)

Returns: boolean

Language: PLPGSQL

DECLARE
  pBankrecid ALIAS FOR $1;
  pSource    ALIAS FOR $2;
  pSourceid  ALIAS FOR $3;
  pCurrrate  ALIAS FOR $4;
  _cleared BOOLEAN;
  _r RECORD;

BEGIN

  SELECT bankrecitem_id, bankrecitem_cleared INTO _r
    FROM bankrecitem
   WHERE ( (bankrecitem_bankrec_id=pBankrecid)
     AND   (bankrecitem_source=pSource)
     AND   (bankrecitem_source_id=pSourceid) );
  IF ( NOT FOUND ) THEN
    _cleared := TRUE;
    INSERT INTO bankrecitem
    (bankrecitem_bankrec_id, bankrecitem_source,
     bankrecitem_source_id, bankrecitem_cleared,
     bankrecitem_curr_rate)
    VALUES
    (pBankrecid, pSource,
     pSourceid, _cleared,
     pCurrrate);
  ELSE
    _cleared := (NOT _r.bankrecitem_cleared);
    UPDATE bankrecitem
       SET bankrecitem_cleared=_cleared,
           bankrecitem_curr_rate=pCurrrate
     WHERE (bankrecitem_id=_r.bankrecitem_id);
  END IF;

  RETURN _cleared;
END;

Function: public.togglebankreccleared(integer, text, integer, numeric, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBankrecid ALIAS FOR $1;
  pSource    ALIAS FOR $2;
  pSourceid  ALIAS FOR $3;
  pCurrrate  ALIAS FOR $4;
  pAmount    ALIAS FOR $5;
  _cleared BOOLEAN;
  _r RECORD;

BEGIN

  SELECT bankrecitem_id, bankrecitem_cleared INTO _r
    FROM bankrecitem
   WHERE ( (bankrecitem_bankrec_id=pBankrecid)
     AND   (bankrecitem_source=pSource)
     AND   (bankrecitem_source_id=pSourceid) );
  IF ( NOT FOUND ) THEN
    _cleared := TRUE;
    INSERT INTO bankrecitem
    (bankrecitem_bankrec_id, bankrecitem_source,
     bankrecitem_source_id, bankrecitem_cleared,
     bankrecitem_curr_rate, bankrecitem_amount)
    VALUES
    (pBankrecid, pSource,
     pSourceid, _cleared,
     pCurrrate, pAmount);
  ELSE
    _cleared := FALSE;
    DELETE FROM bankrecitem 
    WHERE bankrecitem_id = _r.bankrecitem_id;
  END IF;

  RETURN _cleared;
END;

Function: public.togglebomitemcost(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pBomitemid ALIAS FOR $1;
  pEnabled   ALIAS FOR $2;

BEGIN

  IF (pEnabled) THEN
    INSERT INTO bomitemcost
    (bomitemcost_bomitem_id, bomitemcost_costelem_id,
     bomitemcost_lowlevel, bomitemcost_stdcost,
     bomitemcost_posted, bomitemcost_actcost,
     bomitemcost_updated, bomitemcost_curr_id)
    SELECT
     bomitem_id, itemcost_costelem_id,
     itemcost_lowlevel, itemcost_stdcost,
     itemcost_posted, itemcost_actcost,
     itemcost_updated, itemcost_curr_id
    FROM bomitem JOIN itemcost ON (itemcost_item_id=bomitem_item_id)
    WHERE (bomitem_id=pBomitemid);
  ELSE
    DELETE FROM bomitemcost
    WHERE (bomitemcost_bomitem_id=pBomitemid);
  END IF;

  RETURN 0;
END;

Function: public.tonumeric(text, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pText ALIAS FOR $1;
  pDefault ALIAS FOR $2;

BEGIN

  IF (isNumeric(pText)) THEN
    RETURN TO_NUMBER(pText, '999999999999');
  ELSE
    RETURN pDefault;
  END IF;

END;

Function: public.transitwhs()

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _id	INTEGER;

BEGIN
  _id = fetchMetricValue('TransitWarehouse');

  IF (_id IS NOT NULL
      AND EXISTS(SELECT warehous_id FROM whsinfo WHERE (warehous_id=_id)) ) THEN
    RETURN _id;
  END IF;

  SELECT warehous_id INTO _id FROM whsinfo WHERE warehous_transit;

  IF (NOT FOUND) THEN
    _id := NEXTVAL('warehous_warehous_id_seq');

    INSERT INTO whsinfo (
      warehous_id,
      warehous_code,
      warehous_descrip,
      --warehous_fob,
      warehous_active,
      --warehous_counttag_prefix,
      --warehous_counttag_number,
      --warehous_bol_prefix,
      --warehous_bol_number,
      warehous_shipping,
      warehous_useslips,
      warehous_usezones,
      --warehous_aislesize,
      --warehous_aislealpha,
      --warehous_racksize,
      --warehous_rackalpha,
      --warehous_binsize,
      --warehous_binalpha,
      --warehous_locationsize,
      --warehous_locationalpha,
      warehous_enforcearbl,
      warehous_default_accnt_id,
      --warehous_shipping_commission,
      --warehous_cntct_id,
      --warehous_addr_id,
      warehous_taxzone_id
     ) VALUES (
       _id,
      'TRANSIT',
      'Intermediate Warehouse for Inter-Warehouse Transfers',
      --text,
      TRUE,
      --text, 
      --integer, 
      --text, 
      --integer, 
      TRUE,
      FALSE,
      FALSE,
      --integer, 
      --boolean, 
      --integer, 
      --boolean, 
      --integer, 
      --boolean, 
      --integer, 
      --boolean, 
      FALSE,
      fetchMetricValue('UnassignedAccount'),
      --numeric(8,4) default 0.00,
      --integer, 
      --integer, 
      NULL
    );
  END IF;

  PERFORM setMetric('TransitWarehouse', _id);

  RETURN _id;

END;

Function: public.transtype(text, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTransType ALIAS FOR $1;
  pTargetType ALIAS FOR $2;

BEGIN

  IF (pTargetType = 255) THEN
    RETURN TRUE;
  ELSIF (pTargetType = 1) THEN
    RETURN receipts(pTransType);
  ELSIF (pTargetType = 2) THEN
    RETURN issues(pTransType);
  ELSIF (pTargetType = 4) THEN
    RETURN shipments(pTransType);
  ELSIF (pTargetType = 8) THEN
    RETURN adjustments(pTransType);
  ELSIF (pTargetType = 16) THEN
    RETURN transfers(pTransType);
  ELSIF (pTargetType = 32) THEN
    RETURN scraps(pTransType);
  ELSE
    RETURN TRUE;
  END IF;

END;

Function: public.trylock(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pKey1 ALIAS FOR $1;
  pKey2 ALIAS FOR $2;
  _pid integer;
BEGIN

  /* The standard try lock ignores locks made by the current user in same
     session.  Check for ANY lock on this id, whether by this user or not */
  SELECT pid INTO _pid
  FROM pg_locks
  WHERE ((classid=pKey1)
   AND (objid=pKey2)
   AND (objsubid=2));

  IF (FOUND) THEN
    RETURN false;
  ELSE
    RETURN pg_try_advisory_lock(pKey1,pKey2);
  END IF;
   
END;

Function: public.undomerge(text, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSchema       ALIAS FOR $1;
  pTable        ALIAS FOR $2;
  pId           ALIAS FOR $3;
  _qry          TEXT;
  _r            RECORD;
  _result       INTEGER;

BEGIN
  FOR _r IN
    SELECT *
      FROM mrgundo
     WHERE mrgundo_base_schema = pSchema
       AND mrgundo_base_table  = pTable
       AND mrgundo_base_id     = pId
       AND mrgundo_col IS NOT NULL  -- NULL mrgundo_col signals a row to delete on purge
  LOOP
    IF (_r.mrgundo_value IS NULL) THEN
      _qry := 'UPDATE ' || quote_ident(_r.mrgundo_schema)  ||
                    '.' || quote_ident(_r.mrgundo_table)   ||
                ' SET ' || quote_ident(_r.mrgundo_col)     || '= NULL
               WHERE (' || _r.mrgundo_pkey_col || '=' || _r.mrgundo_pkey_id || ');';
    ELSE
      _qry := 'UPDATE ' || quote_ident(_r.mrgundo_schema)  ||
                    '.' || quote_ident(_r.mrgundo_table)   ||
                ' SET ' || quote_ident(_r.mrgundo_col)     ||
              '= CAST(' || quote_literal(_r.mrgundo_value) || ' AS '
                        || quote_ident(_r.mrgundo_type)    || ')
               WHERE (' || _r.mrgundo_pkey_col || '=' || _r.mrgundo_pkey_id || ');';
    END IF;

    EXECUTE _qry;
  END LOOP;

  DELETE FROM mrgundo
   WHERE mrgundo_base_schema = pSchema
     AND mrgundo_base_table  = pTable
     AND mrgundo_base_id     = pId;

  GET DIAGNOSTICS _result = ROW_COUNT;

  RETURN _result;

END;

Function: public.uomusedforitem(integer)

Returns: SET OF uom

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pitemid       ALIAS FOR $1;
  _row          uom%ROWTYPE;
BEGIN
  FOR _row IN SELECT DISTINCT *
              FROM uom
              WHERE uom_id IN (
                SELECT bomitem_uom_id AS uom_id 
                FROM bomitem 
                WHERE (bomitem_item_id=pitemid)
                UNION 
                SELECT cmitem_qty_uom_id 
                FROM cmitem, itemsite 
                WHERE ((cmitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT cmitem_price_uom_id 
                FROM cmitem, itemsite 
                WHERE ((cmitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT coitem_qty_uom_id 
                FROM coitem, itemsite 
                WHERE ((coitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT coitem_price_uom_id 
                FROM coitem, itemsite 
                WHERE ((coitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT invcitem_qty_uom_id 
                FROM invcitem 
                WHERE ((invcitem_item_id=pitemid))
                UNION 
                SELECT invcitem_price_uom_id 
                FROM invcitem 
                WHERE ((invcitem_item_id=pitemid))
                UNION 
                SELECT ipsitem_qty_uom_id 
                FROM ipsiteminfo 
                WHERE (ipsitem_item_id=pitemid)
                UNION 
                SELECT ipsitem_price_uom_id 
                FROM ipsiteminfo 
                WHERE (ipsitem_item_id=pitemid)
                UNION 
                SELECT quitem_qty_uom_id 
                FROM quitem, itemsite 
                WHERE ((quitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT quitem_price_uom_id 
                FROM quitem, itemsite 
                WHERE ((quitem_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
                UNION 
                SELECT womatl_uom_id 
                FROM womatl, itemsite 
                WHERE ((womatl_itemsite_id=itemsite_id)
                   AND (itemsite_item_id=pitemid))
  ) LOOP
    RETURN NEXT _row;
  END LOOP;

  IF (fetchmetricbool('MultiWhs')) THEN
    FOR _row IN SELECT DISTINCT *
                FROM uom
                WHERE uom_id IN (
                  SELECT rahist_uom_id 
                  FROM rahist, itemsite 
                  WHERE ((rahist_itemsite_id=itemsite_id)
                     AND (itemsite_item_id=pitemid))
    ) LOOP
      RETURN NEXT _row;
    END LOOP;
  END IF;

  RETURN;
END;

Function: public.updateabcclass(integer, integer, numeric, numeric, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClasscodeid ALIAS FOR $1;
  pWarehousid ALIAS FOR $2;
  pACutoff ALIAS FOR $3;
  pBCutoff ALIAS FOR $4;
  pStartDate ALIAS FOR $5;
  pEndDate ALIAS FOR $6;
  _updateCount INTEGER;
  _totalValue NUMERIC;
  _cumulativeValue NUMERIC;
  _itemsite RECORD;

BEGIN

  SELECT COUNT(*) INTO _updateCount
  FROM itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND ((item_classcode_id=pClasscodeid) OR (pClasscodeid=-1))
   AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

  IF (_updateCount IS NULL) THEN
    _updateCount := 0;
  ELSE

    UPDATE itemsite
    SET itemsite_abcclass='T'
    FROM item
    WHERE ( (itemsite_item_id=item_id)
     AND ((item_classcode_id=pClasscodeid) OR (pClasscodeid=-1))
     AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

    SELECT SUM(ABS(invhist_qoh_before - invhist_qoh_after) * invhist_unitcost) INTO _totalValue
    FROM invhist, itemsite, item
    WHERE ( (invhist_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (invhist_analyze)
     AND (invhist_transtype ~ '^[IR]')
     AND ((item_classcode_id=pClasscodeid) OR (pClasscodeid=-1))
     AND (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
     AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

    IF ( (_totalValue IS NULL) OR (_totalValue = 0) ) THEN
      UPDATE itemsite
      SET itemsite_abcclass='A'
      WHERE (itemsite_abcclass='T');
    ELSE

      _cumulativeValue := 0;

      FOR _itemsite IN SELECT itemsite_id, item_number,
                              SUM(ABS(invhist_qoh_before - invhist_qoh_after) * invhist_unitcost) AS value
                       FROM invhist, itemsite, item
                       WHERE ( (invhist_itemsite_id=itemsite_id)
                        AND (itemsite_item_id=item_id)
                        AND (invhist_analyze)
                        AND (invhist_transtype ~ '^[IR]')
                        AND ((item_classcode_id=pClasscodeid) OR (pClasscodeid=-1))
                        AND (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
                        AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) )
                       GROUP BY itemsite_id, item_number
                       ORDER BY value DESC LOOP

        IF (_itemsite.value IS NOT NULL) THEN
          _cumulativeValue := _cumulativeValue + _itemsite.value;
        END IF;

        IF ((_cumulativeValue / _totalValue) <= pACutoff) THEN
          UPDATE itemsite
          SET itemsite_abcclass='A'
          WHERE (itemsite_id=_itemsite.itemsite_id);
        ELSE
          IF ((_cumulativeValue / _totalValue) <= pBCutoff) THEN
            UPDATE itemsite
            SET itemsite_abcclass='B'
            WHERE (itemsite_id=_itemsite.itemsite_id);
          ELSE
            UPDATE itemsite
            SET itemsite_abcclass='C'
            WHERE (itemsite_id=_itemsite.itemsite_id);
          END IF;
        END IF;

      END LOOP;

      UPDATE itemsite
      SET itemsite_abcclass='C'
      WHERE (itemsite_abcclass='T');
    END IF;

  END IF;

  RETURN _updateCount;

END;

Function: public.updateabcclass(integer, numeric, numeric, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClasscodeid ALIAS FOR $1;
  pACutoff ALIAS FOR $2;
  pBCutoff ALIAS FOR $3;
  pStartDate ALIAS FOR $4;
  pEndDate ALIAS FOR $5;
  _result INTEGER;

BEGIN

  SELECT updateABCClass(pClassCodeid, -1, pACutoff, pBCutoff, pStartDate, pEndDate) INTO _result;
  RETURN _result;

END;

Function: public.updateabcclass(text, integer, numeric, numeric, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClassCodePattern ALIAS FOR $1;
  pWarehousid ALIAS FOR $2;
  pACutoff ALIAS FOR $3;
  pBCutoff ALIAS FOR $4;
  pStartDate ALIAS FOR $5;
  pEndDate ALIAS FOR $6;
  _updateCount INTEGER;
  _totalValue NUMERIC;
  _cumulativeValue NUMERIC;
  _itemsite RECORD;

BEGIN

  SELECT COUNT(*) INTO _updateCount
  FROM itemsite, item, classcode
  WHERE ( (itemsite_item_id=item_id)
   AND (item_classcode_id=classcode_id)
   AND (itemsite_autoabcclass)
   AND (classcode_code ~ pClassCodePattern)
   AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

  IF (_updateCount IS NULL) THEN
    RETURN 0;
  ELSE

    UPDATE itemsite
    SET itemsite_abcclass='T'
    FROM item, classcode
    WHERE ( (itemsite_item_id=item_id)
     AND (item_classcode_id=classcode_id)
     AND (itemsite_autoabcclass)
     AND (classcode_code ~ pClassCodePattern)
     AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

    SELECT SUM(ABS(invhist_qoh_before - invhist_qoh_after) * invhist_unitcost) INTO _totalValue
    FROM invhist, itemsite, item, classcode
    WHERE ( (invhist_itemsite_id=itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (item_classcode_id=classcode_id)
     AND (invhist_analyze)
     AND (invhist_transtype ~ '^[IR]')
     AND (itemsite_autoabcclass)
     AND (classcode_code ~ pClassCodePattern)
     AND (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
     AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) );

    IF ( (_totalValue IS NULL) OR (_totalValue = 0) ) THEN
      UPDATE itemsite
      SET itemsite_abcclass='A'
      WHERE (itemsite_abcclass='T');
    ELSE

      _cumulativeValue := 0;

      FOR _itemsite IN SELECT itemsite_id, item_number,
                              SUM(ABS(invhist_qoh_before - invhist_qoh_after) * invhist_unitcost) AS value
                       FROM invhist, itemsite, item, classcode
                       WHERE ( (invhist_itemsite_id=itemsite_id)
                        AND (itemsite_item_id=item_id)
                        AND (item_classcode_id=classcode_id)
                        AND (invhist_analyze)
                        AND (invhist_transtype ~ '^[IR]')
                        AND (itemsite_autoabcclass)
                        AND (classcode_code ~ pClassCodePattern)
                        AND (invhist_transdate::DATE BETWEEN pStartDate AND pEndDate)
                        AND ((itemsite_warehous_id=pWarehousid) OR (pWarehousid=-1)) )
                       GROUP BY itemsite_id, item_number
                       ORDER BY value DESC LOOP

        IF (_itemsite.value IS NOT NULL) THEN
          _cumulativeValue := _cumulativeValue + _itemsite.value;
        END IF;

        IF ((_cumulativeValue / _totalValue) <= pACutoff) THEN
          UPDATE itemsite
          SET itemsite_abcclass='A'
          WHERE (itemsite_id=_itemsite.itemsite_id);
        ELSE
          IF ((_cumulativeValue / _totalValue) <= pBCutoff) THEN
            UPDATE itemsite
            SET itemsite_abcclass='B'
            WHERE (itemsite_id=_itemsite.itemsite_id);
          ELSE
            UPDATE itemsite
            SET itemsite_abcclass='C'
            WHERE (itemsite_id=_itemsite.itemsite_id);
          END IF;
        END IF;

      END LOOP;

      UPDATE itemsite
      SET itemsite_abcclass='C'
      WHERE (itemsite_abcclass='T');
    END IF;

  END IF;

  RETURN _updateCount;

END;

Function: public.updateabcclass(text, numeric, numeric, date, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pClassCodePattern ALIAS FOR $1;
  pACutoff ALIAS FOR $2;
  pBCutoff ALIAS FOR $3;
  pStartDate ALIAS FOR $4;
  pEndDate ALIAS FOR $5;
  _result INTEGER;

BEGIN

  SELECT updateABCClass(pClassCodePattern, -1, pACutoff, pBCutoff, pStartDate, pEndDate) INTO _result;
  RETURN _result;

END;

Function: public.updatecharassignment(text, integer, integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetType ALIAS FOR $1;
  pTargetId ALIAS FOR $2;
  pCharId ALIAS FOR $3;
  pValue ALIAS FOR $4;
  _charassid INTEGER;

BEGIN

  SELECT updateCharAssignment(pTargetType, pTargetId, pCharId, pValue, 0) INTO _charassid;

  RETURN _charassid;

END;

Function: public.updatecharassignment(text, integer, integer, text, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTargetType ALIAS FOR $1;
  pTargetId ALIAS FOR $2;
  pCharId ALIAS FOR $3;
  pValue ALIAS FOR $4;
  pPrice ALIAS FOR $5;
  _charassid INTEGER;
  _charassprice NUMERIC;
  _explodedJob BOOLEAN = FALSE;
  _value TEXT;

BEGIN

  -- Check for Valid Assignment
  IF (pTargetType='SI') THEN
    SELECT (item_config AND wo_status != 'O') INTO _explodedJob
        FROM coitem,itemsite,item,wo
        WHERE ((coitem_id=pTargetId)
        AND (itemsite_id=coitem_itemsite_id)
        AND (item_id=itemsite_item_id)
        AND (wo_ordtype='S')
        AND (wo_ordid=coitem_id));
  END IF;
  
  SELECT charass_id,charass_value INTO _charassid, _value
    FROM charass
   WHERE ((charass_target_type=pTargetType)
     AND  (charass_target_id=pTargetId)
     AND  (charass_char_id=pCharId) )
   LIMIT 1;
  IF (FOUND) THEN
    IF (_explodedJob AND pValue != _value) THEN
      RAISE EXCEPTION  'Characteristic may not be updated for Configured Item with exploded Work Order.';
    ELSIF(COALESCE(pValue, '')!='') THEN
        UPDATE charass
        SET charass_value = pValue,
            charass_price = pPrice
        WHERE (charass_id=_charassid);
    ELSE
      DELETE
        FROM charass
       WHERE (charass_id=_charassid);
      _charassid := 0;
    END IF;
  ELSE
    IF ( (_explodedJob) AND (COALESCE(pValue, '')!='') ) THEN
      RAISE EXCEPTION  'Characteristics may not be updated for Configured Item with exploded Work Order.';
    ELSIF(COALESCE(pValue, '')!='') THEN
      SELECT nextval('charass_charass_id_seq') INTO _charassid;
      INSERT INTO charass
            (charass_id, charass_target_type, charass_target_id,
             charass_char_id, charass_value, charass_price)
      VALUES(_charassid, pTargetType, pTargetId,
             pCharId, pValue, pPrice);
    ELSE
      _charassid := 0;
    END IF;
  END IF;

  RETURN _charassid;

END;

Function: public.updatecost(integer, integer, boolean, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  returnVal INTEGER;

BEGIN
  SELECT updateCost($1, $2, $3, $4, baseCurrId()) INTO returnVal;
  RETURN returnVal;
END;

Function: public.updatecost(integer, integer, boolean, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCostelemid ALIAS FOR $2;
  pLevel ALIAS FOR $3;
  pCost ALIAS FOR $4;
  pCurrid ALIAS FOR $5;
  _cost NUMERIC;
  _currId INTEGER;
  _p RECORD;
  _itemcostid INTEGER;

BEGIN

  IF (pCost IS NULL) THEN
    _cost = 0;
  ELSE
    _cost = pCost;
  END IF;

  IF (pCurrId IS NULL) THEN
    _currId := baseCurrID();
  ELSE
    _currId := pCurrId;
  END IF;

  SELECT itemcost_id, itemcost_stdcost INTO _p
  FROM itemcost
  WHERE ((itemcost_costelem_id=pCostelemid)
   AND (itemcost_item_id=pItemid)
   AND (itemcost_lowlevel=pLevel) );

  IF (NOT FOUND) THEN
    IF (_cost > 0) THEN
      SELECT NEXTVAL('itemcost_itemcost_id_seq') INTO _itemcostid;
      INSERT INTO itemcost
      ( itemcost_id, itemcost_item_id, itemcost_costelem_id, itemcost_lowlevel,
        itemcost_stdcost, itemcost_posted, itemcost_actcost, itemcost_updated,
        itemcost_curr_id )
      SELECT _itemcostid, pItemid, costelem_id, pLevel,
             0, startOfTime(), _cost, CURRENT_DATE,
             _currId
      FROM costelem
      WHERE (costelem_id=pCostelemid);

      RETURN _itemcostid;

    ELSE
      RETURN -1;
    END IF;

  ELSIF ( (_p.itemcost_stdcost > 0) OR (_cost > 0) ) THEN
    UPDATE itemcost
    SET itemcost_actcost=_cost,
        itemcost_curr_id = _currId,
        itemcost_updated=CURRENT_DATE
    WHERE (itemcost_id=_p.itemcost_id);

    RETURN _p.itemcost_id;

  ELSE
    DELETE FROM itemcost
    WHERE (itemcost_id=_p.itemcost_id);
 
    RETURN -1;
  END IF;

END;

Function: public.updatecost(integer, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemcostid ALIAS FOR $1;
  pCost ALIAS FOR $2;

BEGIN
  RETURN updateCost(pItemcostid, pCost, baseCurrId());
END;

Function: public.updatecost(integer, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pItemcostid ALIAS FOR $1;
    pCost ALIAS FOR $2;
    pCurrId ALIAS FOR $3;

BEGIN
  IF ( ( SELECT (itemcost_stdcost > 0)
           FROM itemcost
          WHERE (itemcost_id=pItemcostid) )  OR
        (pCost > 0) ) THEN
    UPDATE itemcost
       SET itemcost_actcost=pCost, itemcost_updated=CURRENT_DATE,
           itemcost_curr_id=pCurrId
     WHERE (itemcost_id=pItemcostid);

    RETURN pItemcostid;

  ELSE
    DELETE FROM itemcost
     WHERE (itemcost_id=pItemcostid);

    RETURN -1;
  END IF;

END;

Function: public.updatecost(integer, text, boolean, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  returnVal INTEGER;

BEGIN
  SELECT updateCost($1, $2, $3, $4, baseCurrId()) INTO returnVal;
  RETURN returnVal;
END;

Function: public.updatecost(integer, text, boolean, numeric, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCosttype ALIAS FOR $2;
  pLevel ALIAS FOR $3;
  pCost ALIAS FOR $4;
  pCurrid ALIAS FOR $5;
  _cost NUMERIC;
  _currId INTEGER;
  _p RECORD;
  _itemcostid INTEGER;

BEGIN

  IF (pCost IS NULL) THEN
    _cost = 0;
  ELSE
    _cost = pCost;
  END IF;

  IF (pCurrId IS NULL) THEN
    _currId := baseCurrID();
  ELSE
    _currId := pCurrId;
  END IF;

  SELECT itemcost_id, itemcost_stdcost INTO _p
  FROM itemcost, costelem
  WHERE ( (itemcost_costelem_id=costelem_id)
   AND (itemcost_item_id=pItemid)
   AND (itemcost_lowlevel=pLevel)
   AND (costelem_type=pCosttype) );

  IF (NOT FOUND) THEN
    IF (_cost > 0) THEN
      SELECT NEXTVAL('itemcost_itemcost_id_seq') INTO _itemcostid;
      INSERT INTO itemcost
      ( itemcost_id, itemcost_item_id, itemcost_costelem_id, itemcost_lowlevel,
        itemcost_stdcost, itemcost_posted, itemcost_actcost, itemcost_updated,
        itemcost_curr_id )
      SELECT _itemcostid, pItemid, costelem_id, pLevel,
             0, startOfTime(), _cost, CURRENT_DATE,
             _currId
      FROM costelem
      WHERE (costelem_type=pCosttype);

      RETURN _itemcostid;

    ELSE
      RETURN -1;
    END IF;

  ELSIF ( (_p.itemcost_stdcost > 0) OR (_cost > 0) ) THEN
    UPDATE itemcost
    SET itemcost_actcost=_cost,
        itemcost_curr_id = _currId,
        itemcost_updated=CURRENT_DATE
    WHERE (itemcost_id=_p.itemcost_id);

    RETURN _p.itemcost_id;

  ELSE
    DELETE FROM itemcost
    WHERE (itemcost_id=_p.itemcost_id);
 
    RETURN -1;
  END IF;

END;

Function: public.updatecreditmemoline(api.creditmemoline, api.creditmemoline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pNew ALIAS FOR $1;
  pOld ALIAS FOR $2;
  _check INTEGER;
  _r RECORD;

BEGIN
  SELECT cmitem_id INTO _check
  FROM cmitem
  WHERE ( (cmitem_cmhead_id=getCmheadId(pOld.memo_number, FALSE)) AND (cmitem_linenumber=pOld.line_number) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Credit Memo # % Line Number # not found', pOld.memo_number, pOld.line_number;
  END IF;

  UPDATE cmitem
    SET cmitem_itemsite_id=COALESCE(itemsite_id, -1),
        cmitem_qtycredit=pNew.qty_to_credit,
        cmitem_qtyreturned=pNew.qty_returned,
        cmitem_unitprice=pNew.net_unit_price,
        cmitem_comments=pNew.notes,
        cmitem_rsncode_id=getRsnId(pNew.reason_code),
        cmitem_taxtype_id=taxtype_id,
        cmitem_qty_uom_id=COALESCE(getUomId(pNew.qty_uom), item_inv_uom_id),
        cmitem_qty_invuomratio=CASE WHEN item_id IS NOT NULL THEN itemuomtouomratio(item_id, COALESCE(getUomId(pNew.qty_uom),item_inv_uom_id),item_inv_uom_id)
                                    ELSE 1
                               END,
        cmitem_price_uom_id=COALESCE(getUomId(pNew.price_uom),item_price_uom_id),
        cmitem_price_invuomratio=CASE WHEN item_id IS NOT NULL THEN itemuomtouomratio(item_id, COALESCE(getUomId(pNew.price_uom),item_price_uom_id),item_price_uom_id)
                                      ELSE 1
                                 END
  FROM cmhead LEFT OUTER JOIN item ON (item_id=getItemId(pNew.item_number))
              LEFT OUTER JOIN itemsite ON (itemsite_item_id=item_id AND
                                           itemsite_warehous_id=getWarehousId(pNew.recv_site, 'ALL'))
              LEFT OUTER JOIN taxtype ON (taxtype_id=CASE WHEN pNew.tax_type IS NULL THEN getItemTaxType(item_id,cmhead_taxzone_id)
                                                          WHEN pNew.tax_type = 'None' THEN NULL
                                                          ELSE getTaxTypeId(pNew.tax_type)
                                                     END)
  WHERE cmitem_cmhead_id=cmhead_id
    AND cmhead_number=pOld.memo_number
    AND cmitem_linenumber=pOld.line_number
    AND cmhead_posted=FALSE;

  RETURN TRUE;
END;

Function: public.updatecustomprivs()

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _r RECORD;
BEGIN

  FOR _r IN SELECT priv_id
              FROM priv
             WHERE ((priv_name IN (SELECT priv_name
                                     FROM priv
                                    WHERE (priv_module='Custom')
                                   EXCEPT
                                   SELECT ('Custom'||cmd_privname)
                                     FROM cmd))
               AND  (priv_module='Custom')) LOOP
    -- TODO: something here
    DELETE FROM grppriv WHERE grppriv_priv_id=_r.priv_id;
    DELETE FROM usrpriv WHERE usrpriv_priv_id=_r.priv_id;
    DELETE FROM priv WHERE priv_id=_r.priv_id;
  END LOOP;

  FOR _r IN SELECT ('Custom'||cmd_privname) AS privname
              FROM cmd
            EXCEPT
            SELECT priv_name
              FROM priv
             WHERE (priv_module='Custom') LOOP
    -- TODO: something here
    INSERT INTO priv (priv_module, priv_name, priv_descrip)
              VALUES ('Custom', _r.privname, 'Auto Generated Custom Priv.');
  END LOOP;

  RETURN TRUE;
END;

Function: public.updateinvoicelineitem(api.invoiceline, api.invoiceline)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
	pNew ALIAS FOR $1;
	pOld ALIAS FOR $2;
	_r RECORD;
BEGIN
	UPDATE invcitem SET
		invcitem_linenumber=pNew.line_number,
		invcitem_item_id=COALESCE(item_id, -1),
		invcitem_custpn=pNew.customer_part_number,
		invcitem_number=(CASE WHEN item_id IS NULL THEN pNew.misc_item_number ELSE NULL END),
		invcitem_warehous_id=(CASE WHEN invcitem_warehous_id IS NULL THEN COALESCE(getwarehousid(pNew.site,'ALL'),-1) ELSE NULL END),
		invcitem_descrip=(CASE WHEN item_id IS NULL THEN pNew.misc_item_description ELSE NULL END),
		invcitem_ordered=pNew.qty_ordered,
		invcitem_billed=COALESCE(pNew.qty_billed, 0),
                invcitem_updateinv=COALESCE(pNew.update_inventory,FALSE),
		invcitem_price=COALESCE(pNew.net_unit_price,itemPrice(item_id,invchead_cust_id,
			invchead_shipto_id,pNew.qty_ordered,invchead_curr_id,invchead_orderdate)),
		invcitem_notes=COALESCE(pNew.notes,''),
		invcitem_salescat_id=CASE
			WHEN item_id IS NULL THEN
				(SELECT salescat_id FROM salescat WHERE salescat_name = pNew.sales_category)
			ELSE NULL
		END,
		invcitem_taxtype_id=taxtype_id,
		invcitem_qty_uom_id=CASE
			WHEN item_id IS NOT NULL THEN
				COALESCE((SELECT uom_id FROM uom WHERE (uom_name=pNew.qty_uom)), item_price_uom_id)
			ELSE NULL
		END,
		invcitem_qty_invuomratio=CASE
			WHEN item_id IS NOT NULL THEN
				itemuomtouomratio(item_id,
					COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.qty_uom),item_price_uom_id),
					item_price_uom_id
				)
			ELSE 1
		END,
		invcitem_price_uom_id=CASE
			WHEN item_id IS NOT NULL THEN
				COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.price_uom),item_price_uom_id)
			ELSE NULL
		END,
		invcitem_price_invuomratio=CASE
			WHEN item_id IS NOT NULL THEN
				itemuomtouomratio(item_id,
					COALESCE((SELECT uom_id FROM uom WHERE uom_name=pNew.price_uom),item_price_uom_id),
					item_price_uom_id
				)
			ELSE 1
		END,
                invcitem_rev_accnt_id=getGlAccntId(alternate_rev_account)
	FROM invchead
		LEFT OUTER JOIN item ON (item_id=getItemId(pNew.item_number))
		LEFT OUTER JOIN taxtype ON (taxtype_id=CASE
			WHEN pNew.tax_type IS NULL THEN getItemTaxType(item_id,invchead_taxzone_id)
			WHEN pNew.tax_type = 'None' THEN NULL
			ELSE (SELECT taxtype_id FROM taxtype WHERE taxtype_name=pNew.tax_type)
		END)
	WHERE invcitem_invchead_id=invchead_id
		AND invcitem_linenumber=pOld.line_number
		AND invchead_invcnumber=pOld.invoice_number
		AND invchead_posted=FALSE;
	RETURN TRUE;
END;

Function: public.updateitemcost(integer, integer, integer, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pItemId ALIAS FOR $1;
pCostElemId ALIAS FOR $2;
pCurrId ALIAS FOR $3;
pCost ALIAS FOR $4;
pPostToStandard ALIAS FOR $5;
_itemcost_id INTEGER;
_update_return INTEGER;
_postcost_return BOOLEAN;

--This function is used with the api.itemcost View for updating
--the itemcost table

BEGIN
  SELECT itemcost_id INTO _itemcost_id
  FROM itemcost
  WHERE ( (itemcost_item_id = pItemId) AND (itemcost_costelem_id = pCostElemId) );

  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'itemcost % not found for. ', pItemId || ' & ' || pCostElemId;
  END IF;

  IF (pCost IS NULL OR pCost < 0) THEN
    RAISE EXCEPTION 'itemcost Actual Cost Invalid ', pCost;
  END IF;
  
  IF (pCost > 0) THEN
    UPDATE itemcost
    SET itemcost_actcost=pCost,
        itemcost_curr_id = pCurrId
    WHERE (itemcost_id=_itemcost_id);

    --Only Post Cost to standard if the parameter is set to true
    IF (pPostToStandard) THEN
      IF (NOT checkPrivilege('PostStandardCosts')) THEN
        RAISE EXCEPTION 'You do not have privileges to poststandard itemcosts. Set api.itemcost post_to_standard to false';
      END IF;
      SELECT postcost(_itemcost_id) INTO _postcost_return;       
      IF (NOT _postcost_return) THEN
        RETURN -2;
      END IF;
    END IF;
  ELSE 
    RETURN -1;
  END IF;

  RETURN _itemcost_id;
  
END;

Function: public.updateitemsiteleadtime(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pPad ALIAS FOR $2;
  _p RECORD;
  _materialLeadTime INTEGER;
  _productionLeadTime INTEGER;
  _leadTime INTEGER;

BEGIN

  SELECT item_type, itemsite_wosupply INTO _p
  FROM item, itemsite
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_id=pitemsiteid) );
  
  IF ( (_p.item_type IN ('M', 'P')) ) THEN

    IF (_p.item_type = 'M') THEN
      SELECT COALESCE(MAX(component.itemsite_leadtime), 0) INTO _materialLeadTime
      FROM bomitem, itemsite AS parent, itemsite AS component
      WHERE ( (bomitem_parent_item_id=parent.itemsite_item_id)
       AND (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id))
       AND (bomitem_item_id=component.itemsite_item_id)
       AND (parent.itemsite_warehous_id=component.itemsite_warehous_id)
       AND (parent.itemsite_id=pItemsiteid) );

      SELECT COALESCE(MAX(booitem_execday), 0) INTO _productionLeadTime
      FROM xtmfg.booitem, itemsite
      WHERE ( (booitem_item_id=itemsite_item_id)
       AND (booitem_rev_id=getActiveRevId('BOO',booitem_item_id))
       AND (itemsite_id=pItemsiteid) );

      _leadTime := (_materialLeadTime + _productionLeadTime + pPad);

    ELSIF (_p.item_type IN ('P')) THEN
      SELECT COALESCE(MAX(itemsrc_leadtime), 0) INTO _leadTime
      FROM itemsrc, itemsite
      WHERE ( (itemsite_item_id=itemsrc_item_id)
       AND (itemsite_id=pItemsiteid) );

      _leadTime := (_leadTime + pPad);
    END IF;

  ELSE
    _leadTime = pPad;
  END IF;

  UPDATE itemsite
  SET itemsite_leadtime=_leadTime
  WHERE (itemsite_id=pItemsiteid);

  RETURN _leadTime;

END;

Function: public.updatelistprice(integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pUpdateBy ALIAS FOR $2;

BEGIN

  UPDATE item
  SET item_listprice = (item_listprice * pUpdateBy)
  WHERE (item_id=pItemid);

  RETURN 1;

END;

Function: public.updatelowerusercosts(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;

BEGIN
    RETURN updateLowerUserCosts(pItemid, TRUE);
END;

Function: public.updatelowerusercosts(integer, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid	ALIAS FOR $1;
  pUpdateActual	ALIAS FOR $2;
  _bomitem RECORD;
  _type CHAR(1);

BEGIN

  SELECT item_type INTO _type
  FROM item
  WHERE (item_id=pItemid);

  IF (_type IN ('M', 'F', 'B', 'T')) THEN
    FOR _bomitem IN SELECT DISTINCT costelem_type
                    FROM ( SELECT COALESCE(bc.costelem_type, ic.costelem_type) AS costelem_type
                           FROM bomitem(pItemid)
                             JOIN item ON (item_id=bomitem_item_id AND item_type <> 'T')
                             JOIN itemcost ON (itemcost_item_id=bomitem_item_id)
                             JOIN costelem ic ON (ic.costelem_id=itemcost_costelem_id AND NOT ic.costelem_sys)
                             LEFT OUTER JOIN bomitemcost ON (bomitemcost_bomitem_id=bomitem_id)
                             LEFT OUTER JOIN costelem bc ON (bc.costelem_id=bomitemcost_costelem_id AND NOT bc.costelem_sys)
                           WHERE ( CURRENT_DATE BETWEEN bomitem_effective AND (bomitem_expires - 1) )

                           UNION SELECT costelem_type
                           FROM itemcost, costelem
                           WHERE ( (itemcost_costelem_id=costelem_id)
                            AND (itemcost_item_id=pItemid) ) ) AS data LOOP

      PERFORM updateSorACost( pItemid, _bomitem.costelem_type,
			      TRUE, lowerCost(pItemid, _bomitem.costelem_type, pUpdateActual),
			      pUpdateActual);
    END LOOP;

  ELSIF (_type = 'C') THEN
    FOR _bomitem IN SELECT DISTINCT costelem_type
                    FROM ( SELECT costelem_type
                           FROM itemcost, costelem,
                                xtmfg.bbomitem
                           WHERE ( (bbomitem_item_id=pItemid)
                            AND ( CURRENT_DATE BETWEEN bbomitem_effective
                                               AND (bbomitem_expires - 1) )
                            AND (NOT costelem_sys)
                            AND (bbomitem_item_id=itemcost_item_id)
                            AND (itemcost_costelem_id=costelem_id) ) 

                           UNION SELECT costelem_type
                           FROM itemcost, costelem,
                                xtmfg.bbomitem AS t,
                                xtmfg.bbomitem AS s
                           WHERE ( (t.bbomitem_item_id=pItemid)
                            AND ( CURRENT_DATE BETWEEN s.bbomitem_effective
                                               AND (s.bbomitem_expires - 1) )
                            AND ( CURRENT_DATE BETWEEN t.bbomitem_effective
                                               AND (t.bbomitem_expires - 1) )
                            AND (s.bbomitem_parent_item_id=t.bbomitem_parent_item_id)
                            AND (NOT costelem_sys)
                            AND (s.bbomitem_item_id=itemcost_item_id)
                            AND (itemcost_costelem_id=costelem_id) ) ) AS data LOOP

      PERFORM updateSorACost( pItemid, _bomitem.costelem_type,
			      TRUE, lowerCost(pItemid, _bomitem.costelem_type, pUpdateActual),
			      pUpdateActual);
    END LOOP;
  END IF;

  RETURN 1;

END;

Function: public.updatelowlevel(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE

  pLowlevel ALIAS FOR $1;
  _num_back INTEGER;

BEGIN

  UPDATE costUpdate SET costUpdate_lowlevel_code = (pLowlevel + 1)
    WHERE costUpdate_item_id IN (
	  SELECT bomitem_item_id
	  FROM bomitem JOIN costUpdate ON (bomitem_parent_item_id = costUpdate_item_id)
	  WHERE ((costUpdate_lowlevel_code = pLowlevel)
            AND  (bomitem_rev_id=getActiveRevId('BOM',bomitem_parent_item_id))
	    AND  (CURRENT_DATE BETWEEN bomitem_effective
                                               AND (bomitem_expires - 1))))
      AND costUpdate_lowlevel_code >= pLowlevel;

  GET DIAGNOSTICS _num_back = ROW_COUNT;

  RETURN _num_back;

END;

Function: public.updateoutlevel(integer, integer, integer[])

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDays ALIAS FOR $2;
  pPeriods ALIAS FOR $3;
  _cursor INTEGER;
  _periodid INTEGER;
  _usage NUMERIC;
  _totalUsage NUMERIC;
  _totalDays INTEGER;
  _outLevel NUMERIC;
  _averageUsage NUMERIC;

BEGIN

  _cursor := 1;
  _totalUsage := 0;
  _totalDays := 0;

  _periodid = pPeriods[_cursor];
  WHILE (_periodid IS NOT NULL) LOOP
    SELECT COALESCE(SUM(invhist_invqty), 0) INTO _usage
    FROM invhist
    WHERE ( (invhist_itemsite_id=pItemsiteid)
     AND ( invhist_transdate::DATE BETWEEN findPeriodStart(_periodid)
                                   AND findPeriodEnd(_periodid) )
     AND (invhist_transtype IN ('SH', 'IM')) );

    _totalUsage := (_totalUsage + _usage);

    _totalDays := ( _totalDays + ( findPeriodEnd(_periodid) -
                                   findPeriodStart(_periodid) + 1 ) );

    _cursor := (_cursor + 1);
    _periodid = pPeriods[_cursor];
  END LOOP;

  IF (_totalDays > 0) THEN
    _outLevel := round(_totalUsage / _totalDays * pDays);

    IF (_outLevel > 0) THEN
      UPDATE itemsite
      SET itemsite_ordertoqty = _outLevel
      WHERE (itemsite_id=pItemsiteid);
    ELSE
      UPDATE itemsite
      SET itemsite_ordertoqty = 0
      WHERE (itemsite_id=pItemsiteid);
    END IF;

    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.updateprice(integer, bpchar, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIpsitemid ALIAS FOR $1;
  pUpdateType ALIAS FOR $2;
  pUpdateBy ALIAS FOR $3;

BEGIN

  IF (pUpdateType IN('V')) THEN
    UPDATE ipsitem
    SET ipsitem_price = (ipsitem_price + pUpdateBy)
    WHERE (ipsitem_id=pIpsitemid);
    RETURN 1;
  ELSE
    UPDATE ipsitem
    SET ipsitem_price = (ipsitem_price * pUpdateBy)
    WHERE (ipsitem_id=pIpsitemid);
    RETURN 1;
  END IF;

END;

Function: public.updateprice(integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pIpsitemid ALIAS FOR $1;
  pUpdateBy ALIAS FOR $2;

BEGIN

  RETURN updatePrice(pIpsitemid, 'P', pUpdateBy);
  
END;


Function: public.updatepricesbypricingschedule(pupdatecharprices integer, pupdateby bpchar, pupdatetype numeric, pipsheadid boolean)

Returns: numeric

Language: PLPGSQL

DECLARE
  _percentMultiplier NUMERIC;
  _currencyDecimals INTEGER;
  _itemRows INTEGER :=0;
  _charRows INTEGER :=0;

BEGIN

	IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
		RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
	END IF;

	-- Get the current user's currency precision
	SELECT COALESCE(locale_curr_scale, 2) INTO _currencyDecimals
	FROM locale, usr
	WHERE usr_locale_id = locale_id AND usr_username = CURRENT_USER;

	IF (pUpdateType = 'V') THEN
		UPDATE ipsitem
		SET ipsitem_price = noNeg(ROUND( (ipsitem_price + pUpdateBy), _currencyDecimals))
		WHERE (ipsitem_ipshead_id = pIpsHeadId);	

		GET DIAGNOSTICS _itemRows = ROW_COUNT;
		
	ELSE
		_percentMultiplier := (1.0 + (pUpdateBy / 100.0));

		UPDATE ipsitem
		SET ipsitem_price = noNeg(ROUND( (ipsitem_price * _percentMultiplier), _currencyDecimals))
		WHERE (ipsitem_ipshead_id = pIpsHeadId);
		
		GET DIAGNOSTICS _itemRows = ROW_COUNT;
		
		IF (pUpdateCharPrices) THEN
			UPDATE ipsitemchar 
			SET ipsitemchar_price = noNeg(ROUND( (ipsitemchar_price * _percentMultiplier), _currencyDecimals))
			FROM ipsitem
			WHERE ipsitemchar_ipsitem_id = ipsitem_id AND ipsitem_ipshead_id = pIpsHeadId;
			
			GET DIAGNOSTICS _charRows = ROW_COUNT;
		END IF;

	END IF;
	
	RETURN _itemRows + _charRows;

END;

Function: public.updatepricesbyproductcategory(pupdatecharprices integer, pupdateby text, pupdatetype bpchar, pprodcatpattern numeric, pprodcatid boolean)

Returns: numeric

Language: PLPGSQL

DECLARE
  _percentMultiplier NUMERIC;
  _currencyDecimals INTEGER;
  _itemRows INTEGER :=0;
  _charRows INTEGER :=0;

BEGIN

	IF NOT (checkPrivilege('MaintainPricingSchedules')) THEN
		RAISE EXCEPTION 'You do not have privileges to maintain Price Schedules.';
	END IF;

	-- Get the current user's currency precision
	SELECT COALESCE(locale_curr_scale, 2) INTO _currencyDecimals
	FROM locale, usr
	WHERE usr_locale_id = locale_id AND usr_username = CURRENT_USER;
	
	_percentMultiplier := (1.0 + (pUpdateBy / 100.0));
	
	IF (pUpdateType = 'V') THEN
	
		IF (pProdCatId IS NOT NULL) THEN
			-- Specified category id
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price + pUpdateBy), _currencyDecimals ))
			FROM item
			WHERE 
				ipsitem_item_id = item_id
				AND item_prodcat_id = pProdCatId;
			
		ELSIF (pProdCatPattern IS NOT NULL) THEN
			-- Pattern match category
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price + pUpdateBy), _currencyDecimals ))
			FROM item
			WHERE 
				ipsitem_item_id = item_id
				AND item_prodcat_id IN (
					SELECT prodcat_id FROM prodcat 
					WHERE (prodcat_code ~ pProdCatPattern) 
				);		
		ELSE
			-- All categories
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price + pUpdateBy), _currencyDecimals ));
		END IF;
		
		GET DIAGNOSTICS _itemRows = ROW_COUNT;
		
	ELSE
		
		IF (pProdCatId IS NOT NULL) THEN
			-- Specified category id
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price * _percentMultiplier), _currencyDecimals ))
			FROM item
			WHERE 
				ipsitem_item_id = item_id
				AND item_prodcat_id = pProdCatId;
				
			GET DIAGNOSTICS _itemRows = ROW_COUNT;

			IF(pUpdateCharPrices) THEN
				UPDATE ipsitemchar
				SET ipsitemchar_price = noNeg(ROUND( (ipsitemchar_price * _percentMultiplier), _currencyDecimals ))
				FROM ipsitem, item
				WHERE
					item_prodcat_id = pProdCatId
					AND ipsitem_item_id = item_id
					AND ipsitemchar_ipsitem_id = ipsitem_id;
				
				GET DIAGNOSTICS _charRows = ROW_COUNT;
			END IF;
			
		ELSIF (pProdCatPattern IS NOT NULL) THEN
			-- Pattern match category
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price * _percentMultiplier), _currencyDecimals ))
			FROM item
			WHERE 
				item_prodcat_id IN (
					SELECT prodcat_id FROM prodcat 
					WHERE (prodcat_code ~ pProdCatPattern ) 
				)
				AND ipsitem_item_id = item_id;
			
			GET DIAGNOSTICS _itemRows = ROW_COUNT;

			IF(pUpdateCharPrices) THEN
				UPDATE ipsitemchar
				SET ipsitemchar_price = noNeg(ROUND( (ipsitemchar_price * _percentMultiplier), _currencyDecimals ))
				FROM ipsitem, item
				WHERE
					item_prodcat_id IN (
						SELECT prodcat_id FROM prodcat 
						WHERE (prodcat_code ~ pProdCatPattern ) 
					)
					AND ipsitem_item_id = item_id
					AND ipsitemchar_ipsitem_id = ipsitem_id;
				
				GET DIAGNOSTICS _charRows = ROW_COUNT;
			END IF;
			
		ELSE
			-- All categories
			UPDATE ipsitem 
			SET ipsitem_price = noNeg(ROUND( (ipsitem_price * _percentMultiplier), _currencyDecimals ));
			
			GET DIAGNOSTICS _itemRows = ROW_COUNT;
			
			IF(pUpdateCharPrices) THEN
				UPDATE ipsitemchar
				SET ipsitemchar_price = noNeg(ROUND( (ipsitemchar_price * _percentMultiplier), _currencyDecimals ));
				
				GET DIAGNOSTICS _charRows = ROW_COUNT;
			END IF;
			
		END IF;

	END IF;

	RETURN _itemRows + _charRows;

END;

Function: public.updatereorderlevel(integer, integer, integer[])

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pDays ALIAS FOR $2;
  pPeriods ALIAS FOR $3;
  _cursor INTEGER;
  _periodid INTEGER;
  _usage NUMERIC;
  _totalUsage NUMERIC;
  _totalDays INTEGER;
  _reorderLevel NUMERIC;
  _averageUsage NUMERIC;
  _result	TEXT;

BEGIN

  _cursor := 1;
  _totalUsage := 0;
  _totalDays := 0;

  _periodid = pPeriods[_cursor];
  WHILE (_periodid IS NOT NULL) LOOP
    SELECT COALESCE(SUM(invhist_invqty), 0) INTO _usage
    FROM invhist
    WHERE ( (invhist_itemsite_id=pItemsiteid)
     AND ( invhist_transdate::DATE BETWEEN findPeriodStart(_periodid)
                                   AND findPeriodEnd(_periodid) )
     AND (invhist_transtype IN ('SH', 'IM')) );

    _totalUsage := (_totalUsage + _usage);

    _totalDays := ( _totalDays + ( findPeriodEnd(_periodid) -
                                   findPeriodStart(_periodid) + 1 ) );

    _cursor := (_cursor + 1);
    _periodid = pPeriods[_cursor];
  END LOOP;

  IF (_totalDays > 0) THEN
    _reorderLevel := round(_totalUsage / _totalDays * pDays);

    SELECT itemsite_stocked INTO _result from itemsite WHERE (itemsite_id=pItemsiteid);
    IF (_reorderLevel = 0 AND _result='t') THEN
      _reorderLevel := 1;
    END IF;
    
    IF (_reorderLevel > 0) THEN
      UPDATE itemsite
      SET itemsite_reorderlevel = _reorderLevel
      WHERE (itemsite_id=pItemsiteid);
    ELSE
      UPDATE itemsite
      SET itemsite_reorderlevel = 0
      WHERE (itemsite_id=pItemsiteid);
    END IF;

    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.updatereorderlevel(integer[], integer, boolean, integer[])

Returns: SET OF reordlvl

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteids 		ALIAS FOR $1;
  pDays 		ALIAS FOR $2;
  pAddLeadtime		ALIAS FOR $3;
  pPeriodIds 		ALIAS FOR $4;
  _icursor 		INTEGER := 1;
  _pcursor 		INTEGER := 1;
  _totalUsage 		NUMERIC := 0;
  _totalDays 		INTEGER := 0;
  _reorderLevel 	NUMERIC := 0;
  _result		TEXT;
  _usage		NUMERIC;
  _averageUsage 	NUMERIC;
  _row reordlvl		%ROWTYPE;

BEGIN
  -- Validate
  IF (pItemsiteIds[1] IS NULL OR pPeriodIds[1] IS NULL) THEN
    RETURN;
  END IF;
  
  -- Calculate total days
  FOR _pcursor IN 1..ARRAY_UPPER(pPeriodIds,1) 
  LOOP
    _totalDays := ( _totalDays + ( findPeriodEnd(pPeriodIds[_pcursor]) -
                                      findPeriodStart(pPeriodIds[_pcursor]) + 1 ) );
  END LOOP;

  --  Loop through each itemsite id
  FOR _icursor IN 1..ARRAY_UPPER(pItemsiteIds,1)
  LOOP
      -- Get itemsite data
    SELECT itemsite_id,
      item_id,
      warehous_code,
      item_number,
      item_descrip1,
      itemsite_leadtime,
      0,
      itemsite_reorderlevel,
      0,
      0,
      0
      INTO _row
    FROM itemsite
      JOIN item ON (itemsite_item_id=item_id)
      JOIN whsinfo ON (itemsite_warehous_id=warehous_id)
    WHERE (itemsite_id=pItemsiteIds[_icursor]);

    IF (FOUND) THEN
      IF (pAddLeadtime) THEN
        _row.reordlvl_daysofstock := pDays + _row.reordlvl_leadtime;
      ELSE
        _row.reordlvl_daysofstock := pDays;
      END IF;
      
      --  Loop through each period id
      FOR _pcursor IN 1..ARRAY_UPPER(pPeriodIds,1) 
      LOOP
        -- Sum days and usage shipping and inventory transactions
        SELECT COALESCE(SUM(invhist_invqty), 0) INTO _usage
        FROM invhist
        WHERE ( (invhist_itemsite_id=pItemsiteIds[_icursor])
         AND ( invhist_transdate::DATE BETWEEN findPeriodStart(pPeriodIds[_pcursor])
                                       AND findPeriodEnd(pPeriodIds[_pcursor]) )
         AND (invhist_transtype IN ('SH', 'IM')) );

        _totalUsage := (_totalUsage + _usage);

      END LOOP;

      -- Calculate reorder level
      IF (_totalDays > 0) THEN
        _reorderLevel := round(_totalUsage / _totalDays * _row.reordlvl_daysofstock);
      END IF;
  
      IF (_reorderLevel <= 0) THEN
        _reorderLevel := 0;
      END IF;

      SELECT itemsite_stocked INTO _result from itemsite WHERE (itemsite_id=pItemsiteIds[_icursor]);
      IF (_reorderLevel = 0 AND _result='t') THEN
        _reorderLevel := 1;
      END IF;

      -- Set values
      _row.reordlvl_total_days		:= _totalDays;
      _row.reordlvl_total_usage	:= _totalUsage;
      _row.reordlvl_calc_level		:= _reorderLevel;

      -- Return result
      RETURN NEXT _row;
    END IF;

    _usage		:= 0;
    _averageUsage	:= 0;
    _totalUsage		:= 0;
    _reorderLevel	:= 0;
  END LOOP;

  RETURN;
END;

Function: public.updateretainedearnings(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pYearPeriodid ALIAS FOR $1;
  _r RECORD;
  _n RECORD;
  _c RECORD;
  _beginningPeriodid INTEGER;
  _trialbalid INTEGER;
  _accntid INTEGER;
  _totalProfitLoss      NUMERIC;
  _periodid INTEGER;
  _forwardupdate INTEGER;
BEGIN

--  First thing we need to do is to get the yearperiod

  SELECT * INTO _r FROM yearperiod where yearperiod_id = pYearPeriodid;

  IF (NOT FOUND) THEN
    RETURN -6;
  END IF;

--  Now we need to find the next yearperiod

  SELECT * INTO _n FROM yearperiod WHERE yearperiod_start = _r.yearperiod_end + interval '1 day';

  IF (NOT FOUND) THEN
    RETURN -4;
  END IF;

--  Now we have to find where to stick the end of year data

  SELECT period_id INTO _periodid FROM period WHERE period_start = _n.yearperiod_start;

  IF (NOT FOUND) THEN
    RETURN -8;
  END IF;

--  Loop through companies and process each one

  IF (coalesce(fetchMetricValue('GLCompanySize'),0) = 0) THEN
  --  Process for installs not using company segment
  --  Now we need to get the default account number for year end closing

    SELECT CAST ( metric_value AS integer ) INTO _accntid FROM metric WHERE metric_name = 'YearEndEquityAccount';

    IF (NOT FOUND) THEN
      RETURN -7;
    END IF;

  --  So far so good.  Now we need to calculate the profit-loss for the year that we are closing

    SELECT SUM(gltrans_amount) INTO _totalProfitLoss
     FROM gltrans, accnt
     WHERE ( (gltrans_accnt_id = accnt_id)
       AND   (accnt_type IN ( 'R', 'E' ) )
       AND   (gltrans_posted)
       AND   (NOT gltrans_deleted)
       AND   (gltrans_date between _r.yearperiod_start and _r.yearperiod_end ) );
    IF (_totalProfitLoss IS NULL) THEN
      _totalProfitLoss := 0;
    END IF;

  -- Get the trailbal_id

    SELECT trialbal_id INTO _trialbalid
      FROM trialbal
     WHERE ( (trialbal_period_id = _periodid )
       AND   (trialbal_accnt_id = _accntid) );

    IF (NOT FOUND) THEN
      RETURN -9;
    END IF;

  -- Lets do the update for the trialbal

    UPDATE trialbal
       SET trialbal_beginning = trialbal_beginning - trialbal_yearend + _totalProfitLoss,
           trialbal_ending = trialbal_beginning - trialbal_yearend + _totalProfitLoss,
           trialbal_yearend = _totalProfitLoss
     WHERE trialbal_id = _trialbalid;

  -- Now the forward update

    SELECT forwardupdatetrialbalance(_trialbalid) INTO _forwardupdate;
    
  ELSE  -- Process for a multi-company set up
  
    FOR _c IN
      SELECT company_number, company_yearend_accnt_id
      FROM company
    LOOP
  --  Calculate the profit-loss for the year that we are closing

      SELECT SUM(gltrans_amount) INTO _totalProfitLoss
       FROM gltrans, accnt
       WHERE ( (gltrans_accnt_id = accnt_id)
         AND   (accnt_type IN ( 'R', 'E' ) )
         AND   (gltrans_posted)
         AND   (NOT gltrans_deleted)
         AND   (accnt_company = _c.company_number)
         AND   (gltrans_date between _r.yearperiod_start and _r.yearperiod_end ) );
      IF(_totalProfitLoss IS NULL) THEN
        _totalProfitLoss := 0;
      END IF;

    -- Get the trailbal_id

      SELECT trialbal_id INTO _trialbalid
        FROM trialbal
          JOIN accnt ON (trialbal_accnt_id=accnt_id)
       WHERE ( (trialbal_period_id = _periodid )
         AND   (trialbal_accnt_id = _c.company_yearend_accnt_id) );

      IF (NOT FOUND) THEN
        -- Create a trial balance record
        SELECT NEXTVAL('trialbal_trialbal_id_seq') INTO _trialbalid;
        INSERT INTO trialbal
          ( trialbal_id, trialbal_accnt_id, trialbal_period_id,
            trialbal_beginning, trialbal_dirty,
            trialbal_ending,
            trialbal_credits,
            trialbal_debits,
            trialbal_yearend )
        VALUES
          ( _trialbalid, _c.company_yearend_accnt_id, _periodid,
            _totalProfitLoss, TRUE,
            _totalProfitLoss,
            0,
            0,
            _totalProfitLoss );
      ELSE
        -- Lets do the update for the trialbal
        UPDATE trialbal
           SET trialbal_beginning = trialbal_beginning - trialbal_yearend + _totalProfitLoss,
               trialbal_ending = trialbal_beginning - trialbal_yearend + _totalProfitLoss,
               trialbal_yearend = _totalProfitLoss
         WHERE trialbal_id = _trialbalid;
      END IF;

    -- Now the forward update

      SELECT forwardupdatetrialbalance(_trialbalid) INTO _forwardupdate;

    END LOOP;
  END IF;

  RETURN 0;

END;

Function: public.updatesoracost(integer, text, boolean, numeric, boolean)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid	ALIAS FOR $1;
  pCosttype	ALIAS FOR $2;
  pLevel	ALIAS FOR $3;
  pCost		ALIAS FOR $4;
  pUpdateActual	ALIAS FOR $5;

BEGIN
    IF (pUpdateActual) THEN
	RETURN updateCost(pItemid, pCosttype, pLevel, pCost);
    ELSE
	RETURN updateStdCost(pItemid, pCosttype, pLevel, pCost);
    END IF;
END;

Function: public.updatestdcost(integer, numeric, numeric, text, text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pItemcostid	ALIAS FOR $1;
    pNewcost	ALIAS FOR $2;
    pOldcost	ALIAS FOR $3;
    pDocNumber	ALIAS FOR $4;
    pNotes	ALIAS FOR $5;
    _itemcostid	INTEGER;
    _r		RECORD;
    _newcost	NUMERIC;
    _oldcost	NUMERIC;

BEGIN
  IF (pNewcost IS NULL) THEN
    _newcost := 0;
  ELSE
    _newcost := pNewcost;
  END IF;
  IF (pOldcost IS NULL) THEN
    _oldcost := 0;
  ELSE
    _oldcost := pOldcost;
  END IF;

  IF (_newcost > 0) THEN
    UPDATE itemcost
    SET itemcost_stdcost=_newcost,
        itemcost_posted=CURRENT_DATE
    WHERE (itemcost_id=pItemcostid);
  END IF;

--  Distribute to G/L, debit Inventory Asset, credit Inventory Cost Variance
  FOR _r IN SELECT itemsite_id, (itemsite_qtyonhand + itemsite_nnqoh) AS totalQty,
                   costcat_invcost_accnt_id, costcat_asset_accnt_id,
                   itemsite_costmethod
            FROM itemcost, itemsite, costcat
            WHERE ( (itemsite_item_id=itemcost_item_id)
             AND (itemsite_costcat_id=costcat_id)
             AND (itemsite_costmethod != 'A')
             AND ((itemsite_qtyonhand + itemsite_nnqoh) <> 0)
             AND (itemcost_id=pItemcostid) ) LOOP
--    IF (_newcost <> _oldcost) THEN
--      RAISE NOTICE 'itemcost_id = %, Qty = %, Old Cost = %, New Cost = %', pItemcostid, _r.totalQty, _oldcost, _newcost;
--    END IF;
    PERFORM insertGLTransaction( 'P/D', '', pDocNumber, pNotes,
                                 _r.costcat_invcost_accnt_id, _r.costcat_asset_accnt_id, _r.itemsite_id,
                                 ((_newcost - _oldcost) * _r.totalQty),
                                 CURRENT_DATE );
--  Update Itemsite Value if not Average Cost
    IF (_r.itemsite_costmethod <> 'A') THEN
--      RAISE NOTICE 'itemsite_id = %, Qty = %, New Cost = %', _r.itemsite_id, _r.totalQty, _newcost;
      UPDATE itemsite SET itemsite_value=(_r.totalQty * stdCost(itemsite_item_id))
      WHERE (itemsite_id=_r.itemsite_id);
    END IF;
  END LOOP;

  IF (_newcost = 0) THEN
    DELETE FROM itemcost
    WHERE (itemcost_id=pItemcostid);

    RETURN FALSE;
  END IF;

  IF ( SELECT metric_value
        FROM metric
        WHERE ((metric_name = 'EnableAsOfQOH')
        AND (metric_value = 't'))) THEN
    IF (pNewcost IS NOT NULL) THEN
      _newcost := pNewcost;
    END IF;
    IF (pOldcost IS NULL) THEN
      _oldcost := 0;
    ELSE
      _oldcost := pOldcost;
    END IF;
  --  Distribute to G/L, debit Inventory Asset, credit Inventory Cost Variance
    PERFORM postValueIntoInvBalance(
                  itemsite_id,
                  current_date,
                  asofinvqty(itemsite_id,current_date),
                  asofinvnn(itemsite_id,current_date),
                  _oldcost,
                  _newcost)
       FROM itemsite
       JOIN item ON (itemsite_item_id=item_id)
       JOIN itemcost ON (itemcost_item_id=item_id)
      WHERE((itemsite_costmethod = 'S')
        AND (itemcost_id=pItemcostid));
  END IF;

  RETURN TRUE;

END;

Function: public.updatestdcost(integer, text, boolean, numeric)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
    pItemid	ALIAS FOR $1;
    pCostType	ALIAS FOR $2;
    pLevel	ALIAS FOR $3;
    pCost	ALIAS FOR $4;
    _newCost	NUMERIC;
    _oldCost	NUMERIC := 0;
    _itemcostid	INTEGER;
    _updateRet	BOOLEAN;
    _itemNumber TEXT;

BEGIN
    IF (pCost IS NULL) THEN
	_newCost = 0;
    ELSE
	_newCost = pCost;
    END IF;

    SELECT itemcost_id, itemcost_stdCost, item_number
	INTO _itemcostid, _oldCost, _itemNumber
    FROM itemcost, costelem, item
    WHERE ((itemcost_costelem_id=costelem_id)
      AND  (itemcost_item_id=item_id)
      AND  (item_id=pItemid)
      AND  (itemcost_lowlevel=pLevel)
      AND  (costelem_type=pCosttype));
--    RAISE NOTICE 'updateStdCost(%, %, %, %) has itemcost_id % and stdcost %',
--    				pItemid, pCostType, plevel, _newCost, _itemcostid, _oldCost;

    IF (NOT FOUND) AND (_newCost > 0) THEN
	SELECT NEXTVAL('itemcost_itemcost_id_seq') INTO _itemcostid;
	RAISE NOTICE 'updateStdCost() inserting itemcost_id %', _itemcostid;
	INSERT INTO itemcost
	    (itemcost_id, itemcost_item_id, itemcost_costelem_id,
	     itemcost_lowlevel, itemcost_stdcost, itemcost_posted,
	     itemcost_actcost, itemcost_updated)
	SELECT
	      _itemcostid, pItemid, costelem_id,
	      pLevel, _newCost, CURRENT_DATE,
	      0, CURRENT_DATE
	FROM costelem
	WHERE (costelem_type=pCosttype);
    END IF;

    IF (_itemcostid IS NOT NULL) THEN
	SELECT updateStdCost(_itemcostid, _newCost, _oldCost, 'Post Cost',
               ('Set Standard Cost - ' || pCosttype || ' for item ' || _itemNumber)) INTO _updateRet;
	IF (_updateRet) THEN
	    RETURN _itemcostid;
	END IF;
    END IF;

    RETURN -1;
END;

Function: public.updatetodoitem(integer, text, text, text, integer, integer, integer, date, date, bpchar, date, date, integer, text, boolean, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN updateTodoItem($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, NULL);
END;

Function: public.updatetodoitem(integer, text, text, text, integer, integer, integer, date, date, bpchar, date, date, integer, text, boolean, text, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  ptodoitemid ALIAS FOR  $1;
  pusername   ALIAS FOR  $2;
  pname       ALIAS FOR  $3;
  pdesc       ALIAS FOR  $4;
  pincdtid    ALIAS FOR  $5;
  pcrmacctid  ALIAS FOR  $6;
  pOpheadid   ALIAS FOR  $7;
  pstarted    ALIAS FOR  $8;
  pdue        ALIAS FOR  $9;
  pstatus     ALIAS FOR $10;
  passigned   ALIAS FOR $11;
  pcompleted  ALIAS FOR $12;
  ppriority   ALIAS FOR $13;
  pnotes      ALIAS FOR $14;
  pactive     ALIAS FOR $15;
  powner	ALIAS FOR $16;
  pcntctid	ALIAS FOR $17;

  _priority   INTEGER         := ppriority;
  _status     CHARACTER(1)    := pstatus;
  _incdtid    INTEGER         := pincdtid;
  _crmacctid  INTEGER         := pcrmacctid;
  _opheadid   INTEGER         := pOpheadid;
  _assigned   DATE            := passigned;
  _active     BOOL            := pactive;
  _result     INTEGER;

BEGIN
  IF (pusername IS NULL OR pusername = '') THEN
    RETURN -1;
  END IF;

  IF (pname IS NULL OR pname = '') THEN
    RETURN -2;
  END IF;

  IF (pdue IS NULL) THEN
    RETURN -3;
  END IF;

  IF (ptodoitemid IS NULL OR ptodoitemid <= 0) THEN
    RETURN -10;
  END IF;

  IF (pcompleted IS NOT NULL) THEN
    _status := 'C';
  ELSIF (pstatus IS NULL AND pstarted IS NOT NULL) THEN
    _status := 'I';
  ELSIF (pstatus IS NULL) THEN
    _status := 'N';
  END IF;

  IF (_incdtid <= 0) THEN
    _incdtid := NULL;
  END IF;

  IF (_crmacctid <= 0) THEN
    _crmacctid := NULL;
  END IF;

  IF (_opheadid <= 0) THEN
    _opheadid := NULL;
  END IF;

  IF (_priority <= 0) THEN
    _priority := NULL;
  END IF;

  IF (_assigned IS NULL) THEN
    _assigned := CURRENT_DATE;
  END IF;

  IF (_active IS NULL) THEN
    _active := TRUE;
  END IF;

  UPDATE todoitem SET
      todoitem_username=pusername, todoitem_name=pname, todoitem_description=pdesc,
      todoitem_incdt_id=_incdtid, todoitem_status=_status,
      todoitem_active=_active, todoitem_start_date=pstarted,
      todoitem_due_date=pdue, todoitem_assigned_date=_assigned,
      todoitem_completed_date=pcompleted, todoitem_priority_id=_priority,
      todoitem_notes=pnotes, todoitem_crmacct_id=_crmacctid,
      todoitem_ophead_id=_opheadid, todoitem_owner_username=powner,
      todoitem_cntct_id=pcntctid
  WHERE (todoitem_id=ptodoitemid);

  RETURN ptodoitemid;
END;

Function: public.usedefaultlocation(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  _p RECORD;

BEGIN

  SELECT itemsite_location_id,
         LENGTH(itemsite_location) AS locationlength INTO _p
  FROM itemsite
  WHERE (itemsite_id=pItemsiteid);

  IF (NOT FOUND) THEN
    RETURN FALSE;

  ELSIF (_p.itemsite_location_id <> -1) THEN
    RETURN TRUE;

  ELSIF (_p.locationlength > 0) THEN
    RETURN TRUE;

  ELSE
    RETURN FALSE;
  END IF;

END;

Function: public.usercancreateusers(text)

Returns: boolean

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT rolcreaterole OR rolsuper
  FROM pg_roles
 WHERE rolname=($1);

Function: public.usercanlogin(pusername text)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _isactive  BOOLEAN;
  _mode      TEXT;
BEGIN
  IF (isDBA(pUsername) OR userCanCreateUsers(pUsername)) THEN
    RETURN TRUE;

  ELSIF (pg_has_role(pUsername, 'xtrole', 'member')) THEN
    _mode := COALESCE(fetchMetricText('AllowedUserLogins'), '');

    IF (_mode = 'AdminOnly') THEN
      RETURN FALSE; -- administrators were checked above
    END IF;

    IF (_mode NOT IN ('AdminOnly','ActiveOnly','Any')) THEN
      _mode := 'ActiveOnly';
    END IF;

    SELECT (usrpref_value = 't') INTO _isactive
      FROM usrpref
     WHERE usrpref_username = pUsername
       AND usrpref_name = 'active';

    IF (_isactive OR _mode = 'Any') THEN
      RETURN TRUE;
    END IF;
  END IF;

  RETURN FALSE;
END;

Function: public.userid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pUsername ALIAS FOR $1;
  _userId INTEGER;

BEGIN

  SELECT usesysid INTO _userId
  FROM pg_user
  WHERE (usename=pUsername);

  IF (FOUND) THEN
    RETURN _userId;
  ELSE
    RETURN -1;
  END IF;

END;

Function: public.validateorderqty(integer, numeric, boolean)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemsiteid ALIAS FOR $1;
  pQty ALIAS FOR $2;
  pManual ALIAS FOR $3;
  _p RECORD;
  _qty NUMERIC;

BEGIN

  _qty := pQty;

  SELECT itemsite_useparams,
         CASE WHEN (itemsite_useparams) THEN itemsite_useparamsmanual ELSE FALSE END AS itemsite_useparamsmanual,
         CASE WHEN (itemsite_useparams) THEN itemsite_minordqty ELSE 0.0 END AS itemsite_minordqty,
         CASE WHEN (itemsite_useparams) THEN itemsite_multordqty ELSE 0.0 END AS itemsite_multordqty,
         item_fractional, item_type INTO _p
  FROM itemsite, item
  WHERE ( (itemsite_item_id=item_id)
   AND (itemsite_id=pItemsiteid) );

  IF ( (pManual AND (_p.itemsite_useparamsmanual)) OR
       ((NOT pManual) AND (_p.itemsite_useparams)) ) THEN

    IF (_qty < _p.itemsite_minordqty) THEN
      _qty := _p.itemsite_minordqty;
    END IF;

    IF ( (_p.itemsite_multordqty > 0) AND ((_qty % _p.itemsite_multordqty) > 0) ) THEN
      _qty := ((TRUNC(_qty / _p.itemsite_multordqty) * _p.itemsite_multordqty) + _p.itemsite_multordqty);
    END IF;

  END IF;

  _qty := roundQty(_p.item_fractional, _qty);

  RETURN _qty;

END;

Function: public.validlocation(integer, integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pLocationid ALIAS FOR $1;
  pItemsiteid ALIAS FOR $2;
  _p RECORD;
  
BEGIN

  SELECT location_restrict INTO _p
  FROM location, itemsite
  WHERE ( (location_warehous_id=itemsite_warehous_id)
    AND (itemsite_id=pItemsiteid)
    AND (location_id=pLocationid) );

  IF (FOUND) THEN
    IF (_p.location_restrict) THEN

      SELECT locitem_id INTO _p
      FROM locitem, itemsite
      WHERE ( (locitem_item_id=itemsite_item_id)
       AND (itemsite_id=pItemsiteid)
       AND (locitem_location_id=pLocationid) );

      IF (FOUND) THEN
        RETURN TRUE;
      END IF;

    ELSE
      RETURN TRUE;
    END IF;

  ELSE
    RETURN FALSE;
  END IF;

  RETURN FALSE;

END;

Function: public.valueatshipping(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RETURN valueAtShipping('SO', $1);
END;

Function: public.valueatshipping(text, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pordertype	ALIAS FOR $1;
  plineitemid	ALIAS FOR $2;
  _qty NUMERIC;
  _cost NUMERIC;
  _value NUMERIC;

BEGIN

  IF (pordertype NOT IN ('SO', 'TO')) THEN
    RAISE EXCEPTION '% is not a valid order type', pordertype;
  END IF;

  SELECT COALESCE(SUM(shipitem_qty), 0.0) INTO _qty
  FROM shipitem, shiphead
  WHERE ((shipitem_shiphead_id=shiphead_id)
    AND  (NOT shiphead_shipped)
    AND  (shiphead_order_type=pordertype)
    AND  (shipitem_orderitem_id=plineitemid) );

  IF (pordertype = 'SO') THEN
    SELECT COALESCE(CASE WHEN (itemsite_costmethod = 'N') THEN 0
                         WHEN (itemsite_costmethod = 'S') THEN stdCost(itemsite_item_id)
                         ELSE avgCost(itemsite_item_id)
                    END, 0.0) INTO _cost
    FROM coitem JOIN itemsite ON (itemsite_id=coitem_itemsite_id)
    WHERE (coitem_id=plineitemid);
  ELSE
    SELECT COALESCE(CASE WHEN (itemsite_costmethod = 'N') THEN 0
                         WHEN (itemsite_costmethod = 'S') THEN stdCost(itemsite_item_id)
                         ELSE avgCost(itemsite_item_id)
                    END, 0.0) INTO _cost
    FROM toitem JOIN tohead ON (tohead_id=toitem_tohead_id)
                JOIN itemsite ON ((itemsite_item_id=toitem_item_id) AND
                                  (itemsite_warehous_id=tohead_src_warehous_id))
    WHERE (toitem_id=plineitemid);
  END IF;

  _value := _qty * _cost;

  RETURN _value;

END;

Function: public.voidapcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'voidAPCheck() is deprecated - use voidCheck() instead';
  RETURN voidCheck($1);
END;

Function: public.voidapopenvoucher(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
BEGIN
  RETURN voidApopenVoucher(pApopenid, fetchJournalNumber('AP-VO'));
END;

Function: public.voidapopenvoucher(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pApopenid ALIAS FOR $1;
  pJournalNumber ALIAS FOR $2;
  _apopenid INTEGER;
  _apcreditapplyid INTEGER;
  _reference    TEXT;
  _result INTEGER;
  _sequence INTEGER;
  _totalAmount_base NUMERIC;
  _totalAmount NUMERIC;
  _itemAmount_base NUMERIC;
  _itemAmount NUMERIC;
  _test INTEGER;
  _a RECORD;
  _d RECORD;
  _g RECORD;
  _p RECORD;
  _n RECORD;
  _r RECORD;
  _costx RECORD;
  _pExplain BOOLEAN;
  _pLowLevel BOOLEAN;
  _exchGainFreight NUMERIC;
  _firstExchDateFreight	DATE;
  _tmpTotal		NUMERIC;
  _glDate		DATE;

BEGIN

  _totalAmount_base := 0;
  _totalAmount := 0;
  SELECT fetchGLSequence() INTO _sequence;

--  Cache APOpen Information
  SELECT apopen.* INTO _n
  FROM apopen
  WHERE ( (apopen_doctype='V')
    AND   (apopen_id=pApopenid) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Voucher #% as apopen not found', pApopenid;
  END IF;

--  Cache Voucher Infomation
  SELECT vohead.*,
	 vend_number || '-' || vend_name || ' ' || vohead_reference
							  AS glnotes,
	 COALESCE(pohead_orderdate, vohead_docdate) AS pohead_orderdate,
	 COALESCE(pohead_curr_id, vohead_curr_id) AS pohead_curr_id INTO _p
  FROM vohead JOIN vendinfo ON (vend_id=vohead_vend_id)
              LEFT OUTER JOIN pohead ON (vohead_pohead_id = pohead_id)
  WHERE (vohead_number=_n.apopen_docnumber);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Voucher #% as vohead not found', _n.apopen_docnumber;
  END IF;

  _glDate := COALESCE(_p.vohead_gldistdate, _p.vohead_distdate);

-- there is no currency gain/loss on items, see issue 3892,
-- but there might be on freight, which is first encountered at p/o receipt
  SELECT recv_date::DATE INTO _firstExchDateFreight
  FROM recv
  WHERE (recv_vohead_id = _p.vohead_id);

--  Start by handling taxes
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.vohead_curr_id, round(sum(taxdetail_tax),2), _p.vohead_docdate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('VO', _p.vohead_id, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', _p.vohead_number,
                                _r.tax_sales_accnt_id, 
                                (_r.taxbasevalue * -1),
                                _glDate, _p.glnotes );

    _totalAmount_base := (_totalAmount_base - _r.taxbasevalue);
    _totalAmount := (_totalAmount - _r.tax);
     
  END LOOP;

--  Loop through the vodist records for the passed vohead that
--  are posted against a P/O Item
  FOR _g IN SELECT DISTINCT poitem_id, voitem_qty, poitem_expcat_id,
                            poitem_invvenduomratio,
                            COALESCE(itemsite_id, -1) AS itemsiteid,
                            COALESCE(itemsite_costcat_id, -1) AS costcatid,
                            COALESCE(itemsite_item_id, -1) AS itemsite_item_id,
                            (SELECT SUM(value) 
                             FROM (
                                SELECT SUM(recv_value) AS value
                                FROM recv
                                WHERE (recv_voitem_id=voitem_id)
                             UNION
                                SELECT SUM(poreject_value)*-1 AS value
                                FROM poreject
                                WHERE (poreject_voitem_id=voitem_id)) as data)
                            AS value_base,
                            (poitem_freight_vouchered / poitem_qty_vouchered) * voitem_qty AS vouchered_freight,
                            currToBase(_p.pohead_curr_id, (poitem_freight_vouchered / poitem_qty_vouchered) * voitem_qty, _firstExchDateFreight ) AS vouchered_freight_base,
			    voitem_freight,
			    currToBase(_p.vohead_curr_id, voitem_freight,
                                       _p.vohead_distdate) AS voitem_freight_base
            FROM vodist, voitem,
                 poitem LEFT OUTER JOIN itemsite ON (poitem_itemsite_id=itemsite_id)
            WHERE ( (vodist_poitem_id=poitem_id)
             AND (voitem_poitem_id=poitem_id)
             AND (voitem_vohead_id=vodist_vohead_id)
             AND (vodist_vohead_id=_p.vohead_id)) LOOP

--  Grab the G/L Accounts
    IF (_g.costcatid = -1) THEN
      SELECT pp.accnt_id AS pp_accnt_id,
             lb.accnt_id AS lb_accnt_id INTO _a
      FROM expcat, accnt AS pp, accnt AS lb
      WHERE ( (expcat_purchprice_accnt_id=pp.accnt_id)
       AND (expcat_liability_accnt_id=lb.accnt_id)
       AND (expcat_id=_g.poitem_expcat_id) );
      IF (NOT FOUND) THEN
        RAISE EXCEPTION 'Cannot Void Voucher #% due to unassigned G/L Accounts.', _p.vohead_number;
      END IF;
    ELSE
      SELECT pp.accnt_id AS pp_accnt_id,
             lb.accnt_id AS lb_accnt_id INTO _a
      FROM costcat, accnt AS pp, accnt AS lb
      WHERE ( (costcat_purchprice_accnt_id=pp.accnt_id)
       AND (costcat_liability_accnt_id=lb.accnt_id)
       AND (costcat_id=_g.costcatid) );
      IF (NOT FOUND) THEN
        RAISE EXCEPTION 'Cannot Void Voucher #% due to unassigned G/L Accounts.', _p.vohead_number;
      END IF;
    END IF;

--  Clear the Item Amount accumulator
    _itemAmount_base := 0;
    _itemAmount := 0;

--  Figure out the total posted value for this line item
    FOR _d IN SELECT vodist_id, vodist_amount,
		     _p.vohead_curr_id, vodist_costelem_id,
		     currToBase(_p.vohead_curr_id, vodist_amount,
				_p.vohead_distdate) AS vodist_amount_base
              FROM vodist
              WHERE ( (vodist_vohead_id=_p.vohead_id)
               AND (vodist_poitem_id=_g.poitem_id) ) LOOP

       _pExplain := TRUE;
       SELECT * INTO _costx
         FROM itemcost
        WHERE ( (itemcost_item_id = _g.itemsite_item_id)
          AND   (itemcost_costelem_id = _d.vodist_costelem_id) );

       IF (FOUND) THEN
         _pExplain := _costx.itemcost_lowlevel;
       END IF;

--  Add the Distribution Amount to the Item Amount
      _itemAmount_base := _itemAmount_base + ROUND(_d.vodist_amount_base, 2);
      _itemAmount := _itemAmount + _d.vodist_amount;

    END LOOP;

--  Distribute from the clearing account
    PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
                                _a.lb_accnt_id,
                                round(_g.value_base + _g.vouchered_freight_base, 2),
                                _glDate, _p.glnotes );

--  Attribute the correct portion to currency gain/loss
    _exchGainFreight := 0;
    SELECT currGain(_p.pohead_curr_id, _g.vouchered_freight,
		    _firstExchDateFreight, _p.vohead_distdate )
		    INTO _exchGainFreight;
    IF (round(_exchGainFreight, 2) <> 0) THEN
      PERFORM insertIntoGLSeries(_sequence, 'A/P', 'VO',
                                 text(_p.vohead_number),
                                 getGainLossAccntId(_a.lb_accnt_id), round(_exchGainFreight, 2) * -1,
                                 _glDate, _p.glnotes);
    END IF;

--  Distribute the remaining variance to the Purchase Price Variance account
    IF (round(_itemAmount_base, 2) <> round(_g.value_base, 2)) THEN
      _tmpTotal := round(_itemAmount_base, 2) - round(_g.value_base, 2);
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
                                  _a.pp_accnt_id,
                                  _tmpTotal,
                                  _glDate, _p.glnotes );
    END IF;

--  Distribute the remaining freight variance to the Purchase Price Variance account
    IF (round(_g.voitem_freight_base + _exchGainFreight, 2) <> round(_g.vouchered_freight_base, 2)) THEN
      _tmpTotal := round(_g.voitem_freight_base + _exchGainFreight, 2) - round(_g.vouchered_freight_base, 2);
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
                                  _a.pp_accnt_id,
                                  _tmpTotal,
                                  _glDate, _p.glnotes );
    END IF;

--  Add the distribution amount to the total amount to distribute
    _totalAmount_base := (_totalAmount_base + _itemAmount_base + _g.voitem_freight_base);
    _totalAmount := (_totalAmount + _itemAmount + _g.voitem_freight);

--  Reverse the posting for all the Tagged Receivings for this P/O Item
    UPDATE recv
    SET recv_invoiced=FALSE,
        recv_recvcost_curr_id=basecurrid(),
        recv_recvcost=0,
        recv_vohead_id=NULL,
        recv_voitem_id=NULL
    FROM poitem
    WHERE ( (recv_orderitem_id=poitem_id)
      AND   (recv_order_type='PO')
      AND   (recv_orderitem_id=_g.poitem_id)
      AND   (recv_vohead_id=_p.vohead_id) );

--  Reverse the posting for all the Tagged Rejections for this P/O Item
    UPDATE poreject
    SET poreject_invoiced=FALSE,
        poreject_vohead_id=NULL,
        poreject_voitem_id=NULL
    WHERE ( (poreject_poitem_id=_g.poitem_id)
      AND   (poreject_vohead_id=_p.vohead_id) );

--  Update the qty and freight vouchered fields
    UPDATE poitem
       SET poitem_qty_vouchered = (poitem_qty_vouchered - _g.voitem_qty),
           poitem_freight_vouchered = (poitem_freight_vouchered - _g.voitem_freight)
    WHERE (poitem_id=_g.poitem_id);

  END LOOP;

--  Loop through the vodist records for the passed vohead that
--  are not posted against a P/O Item
--  Skip the tax distributions
  FOR _d IN SELECT vodist_id,
		   currToBase(_p.vohead_curr_id, vodist_amount,
			      _p.vohead_distdate) AS vodist_amount_base,
		   vodist_amount,
		   vodist_accnt_id, vodist_expcat_id
            FROM vodist
            WHERE ( (vodist_vohead_id=_p.vohead_id)
              AND   (vodist_poitem_id=-1)
              AND   (vodist_tax_id=-1) ) LOOP

--  Distribute from the misc. account
    IF (_d.vodist_accnt_id = -1) THEN
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
                                  expcat_exp_accnt_id,
                                  round(_d.vodist_amount_base, 2),
                                  _glDate, _p.glnotes )
      FROM expcat
      WHERE (expcat_id=_d.vodist_expcat_id);
    ELSE
      PERFORM insertIntoGLSeries( _sequence, 'A/P', 'VO', text(_p.vohead_number),
                                  _d.vodist_accnt_id,
                                  round(_d.vodist_amount_base, 2),
                                  _glDate, _p.glnotes );
    END IF;

--  Add the Distribution Amount to the Total Amount
    _totalAmount_base := _totalAmount_base + ROUND(_d.vodist_amount_base, 2);
    _totalAmount := _totalAmount + _d.vodist_amount;

  END LOOP;

  SELECT insertIntoGLSeries( _sequence, 'A/P', 'VO', text(vohead_number),
                             accnt_id, round(_totalAmount_base, 2) * -1,
                             _glDate, _p.glnotes ) INTO _test
  FROM vohead LEFT OUTER JOIN accnt ON (accnt_id=findAPAccount(vohead_vend_id))
  WHERE ( (findAPAccount(vohead_vend_id)=0 OR accnt_id > 0) -- G/L interface might be disabled
    AND   (vohead_id=_p.vohead_id) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Voucher #% due to an unassigned A/P Account.', _p.vohead_number;
  END IF;

  PERFORM postGLSeries(_sequence, pJournalNumber);

--  Create the A/P Open Item
  SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
  _reference := ('Void Voucher #' || _n.apopen_docnumber);
  INSERT INTO apopen
  ( apopen_id, apopen_username, apopen_journalnumber,
    apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
    apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id, apopen_curr_id,
    apopen_amount, apopen_paid, apopen_open, apopen_notes, apopen_discount, apopen_curr_rate )
  SELECT _apopenid, getEffectiveXtUser(), pJournalnumber,
         apopen_vend_id, apopen_docnumber, 'C', apopen_ponumber,
         CURRENT_DATE, CURRENT_DATE, CURRENT_DATE, -1, apopen_curr_id,
         apopen_amount - apopen_paid, 0, TRUE, _reference, TRUE, apopen_curr_rate
    FROM apopen
   WHERE (apopen_id=_n.apopen_id);

  SELECT apcreditapply_id INTO _apcreditapplyid
    FROM apcreditapply
   WHERE ( (apcreditapply_source_apopen_id=_apopenid)
     AND   (apcreditapply_target_apopen_id=_n.apopen_id) );
  IF (FOUND) THEN
    UPDATE apcreditapply
       SET apcreditapply_amount=_n.apopen_amount-_n.apopen_paid
     WHERE (apcreditapply_id=_apcreditapplyid);
  ELSE
    SELECT nextval('apcreditapply_apcreditapply_id_seq') INTO _apcreditapplyid;
    INSERT INTO apcreditapply
           ( apcreditapply_id, apcreditapply_source_apopen_id,
             apcreditapply_target_apopen_id, apcreditapply_amount,
             apcreditapply_curr_id )
    VALUES ( _apcreditapplyid, _apopenid, _n.apopen_id, _n.apopen_amount-_n.apopen_paid, _n.apopen_curr_id );
  END IF;

  SELECT postAPCreditMemoApplication(_apopenid) INTO _result;

  IF (_result < 0) THEN
    RAISE EXCEPTION 'Credit application failed with result %.', _result;
  END IF;

--  Reopen all of the P/O Items that were closed by this Voucher
  UPDATE poitem
  SET poitem_status='O'
  FROM voitem
  WHERE ( (voitem_poitem_id=poitem_id)
    AND   (voitem_close)
    AND   (voitem_vohead_id=_p.vohead_id) );

--  Reopen the P/O
  UPDATE pohead
  SET pohead_status='O'
  WHERE (pohead_id=_p.vohead_pohead_id);

  RETURN pJournalNumber;

END;

Function: public.voidcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid ALIAS FOR $1;

BEGIN

  IF ( SELECT (checkhead_void OR checkhead_posted OR checkhead_replaced)
       FROM checkhead
       WHERE (checkhead_id=pCheckid) ) THEN
    RETURN -1;
  END IF;

  UPDATE checkhead
  SET checkhead_void=TRUE
  WHERE (checkhead_id=pCheckid);

  RETURN 1;

END;

Function: public.voidcreditmemo(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCmheadid ALIAS FOR $1;
  _r RECORD;
  _p RECORD;
  _n RECORD;
  _glSequence INTEGER := 0;
  _glJournal INTEGER := 0;
  _itemlocSeries INTEGER := 0;
  _invhistid INTEGER;
  _test INTEGER;
  _amount NUMERIC;
  _roundedBase NUMERIC;
  _totalAmount NUMERIC   := 0;
  _totalRoundedBase NUMERIC := 0;
  _commissionDue NUMERIC := 0;
  _toApply NUMERIC;
  _toClose BOOLEAN;
  _glDate	DATE;
  _taxBaseValue	NUMERIC	:= 0;

BEGIN

--  Cache C/M information
  SELECT cmhead.*,
         findARAccount(cmhead_cust_id) AS ar_accnt_id,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM cmheadtax
           WHERE ( (taxhist_parent_id = cmhead_id)
             AND   (taxhist_taxtype_id = getAdjustmentTaxtypeId()) ) ) AS adjtax
         INTO _p
  FROM cmhead
  WHERE (cmhead_id=pCmheadid);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Credit Memo as cmhead not found';
  END IF;
  IF (NOT _p.cmhead_posted) THEN
    RETURN -10;
  END IF;

--  Cache AROpen Information
  SELECT aropen.* INTO _n
  FROM aropen
  WHERE ( (aropen_doctype='C')
    AND   (aropen_docnumber=_p.cmhead_number) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Credit Memo as aropen not found';
  END IF;

--  Check for ARApplications
  SELECT arapply_id INTO _test
  FROM arapply
  WHERE (arapply_target_aropen_id=_n.aropen_id)
     OR (arapply_source_aropen_id=_n.aropen_id)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -20;
  END IF;

  _glDate := COALESCE(_p.cmhead_gldistdate, _p.cmhead_docdate);

  SELECT fetchGLSequence() INTO _glSequence;
  SELECT fetchJournalNumber('AR-IN') INTO _glJournal;

--  Start by handling taxes (reverse sense)
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.cmhead_curr_id, round(sum(taxdetail_tax),2), _p.cmhead_docdate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('CM', _p.cmhead_id, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _glSequence, 'A/R', 'CM', _p.cmhead_number,
                                _r.tax_sales_accnt_id, 
                                (_r.taxbasevalue * -1.0),
                                _glDate, ('Void-' || _p.cmhead_billtoname) );

    _totalAmount := _totalAmount + _r.tax * -1;
    _totalRoundedBase := _totalRoundedBase + _r.taxbasevalue * -1;  
  END LOOP;

-- Process line items
  FOR _r IN SELECT *
            FROM creditmemoitem
            WHERE ( (cmitem_cmhead_id=_p.cmhead_id)
              AND   (cmitem_qtycredit <> 0 ) ) LOOP

    IF (_r.extprice <> 0) THEN
--  Debit the Sales Account for the current cmitem (reverse sense)
      _roundedBase := round(currToBase(_p.cmhead_curr_id, _r.extprice, _p.cmhead_docdate), 2);
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'CM', _p.cmhead_number,
                                 CASE WHEN _p.cmhead_rahead_id IS NULL THEN
                                   getPrjAccntId(_p.cmhead_prj_id, salesaccnt_credit_accnt_id)
                                 ELSE
                                   getPrjAccntId(_p.cmhead_prj_id, salesaccnt_returns_accnt_id)
                                 END,
                                 _roundedBase,
                                 _glDate, ('Void-' || _p.cmhead_billtoname) ) INTO _test
      FROM salesaccnt
      WHERE (salesaccnt_id=findSalesAccnt(_r.cmitem_itemsite_id, 'IS', _p.cmhead_cust_id,
                                          _p.cmhead_saletype_id, _p.cmhead_shipzone_id));
      IF (NOT FOUND) THEN
        PERFORM deleteGLSeries(_glSequence);
        RETURN -11;
      END IF;
    END IF;

    _totalAmount := _totalAmount + round(_r.extprice, 2);
    _totalRoundedBase := _totalRoundedBase + _roundedBase;

  END LOOP;

--  Credit the Misc. Account for Miscellaneous Charges (reverse sense)
  IF (_p.cmhead_misc <> 0) THEN
    _roundedBase := round(currToBase(_p.cmhead_curr_id, _p.cmhead_misc, _p.cmhead_docdate), 2);
    SELECT insertIntoGLSeries( _glSequence, 'A/R', 'CM', _p.cmhead_number,
                               getPrjAccntId(_p.cmhead_prj_id, accnt_id),
                               _roundedBase,
                               _glDate, ('Void-' ||_p.cmhead_billtoname) ) INTO _test
    FROM accnt
    WHERE (accnt_id=_p.cmhead_misc_accnt_id);

--  If the Misc. Charges Account was not found then punt
    IF (NOT FOUND) THEN
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;

--  Cache the Misc. Amount distributed
    _totalAmount := _totalAmount + _p.cmhead_misc;
    _totalRoundedBase := _totalRoundedBase + _roundedBase;
  END IF;

--  Debit the Freight Account (reverse sense)
  IF (_p.cmhead_freight <> 0) THEN
    _roundedBase := round(currToBase(_p.cmhead_curr_id, _p.cmhead_freight, _p.cmhead_docdate), 2);
    SELECT insertIntoGLSeries( _glSequence, 'A/R', 'CM', _p.cmhead_number,
                               getPrjAccntId(_p.cmhead_prj_id, accnt_id),
                               _roundedBase,
                               _glDate, ('Void-' || _p.cmhead_billtoname) ) INTO _test
    FROM accnt
    WHERE (accnt_id=findFreightAccount(_p.cmhead_cust_id));

--  If the Freight Charges Account was not found then punt
    IF (NOT FOUND) THEN
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;

--  Cache the Amount Distributed to Freight
    _totalAmount := _totalAmount + _p.cmhead_freight;
    _totalRoundedBase := _totalRoundedBase + _roundedBase;
  END IF;

  _totalAmount := _totalAmount;

--  Credit the A/R for the total Amount (reverse sense)
  IF (_totalAmount <> 0) THEN
    IF (_p.ar_accnt_id != -1) THEN
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'CM', _p.cmhead_number,
                                 _p.ar_accnt_id,
                                 (_totalRoundedBase * -1.0),
                                 _glDate, ('Void-' || _p.cmhead_billtoname) ) INTO _test;
    ELSE
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;
  END IF;

--  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _glJournal) INTO _test;
  IF (_test < 0) THEN
    PERFORM deleteGLSeries(_glSequence);
    RETURN _test;
  END IF;

--  Delete sales history
  DELETE FROM cohisttax
  WHERE (taxhist_parent_id IN (SELECT cohist_id
                               FROM cohist
                               WHERE (cohist_doctype='C' AND cohist_ordernumber=_p.cmhead_number)));

  DELETE FROM cohist
  WHERE (cohist_doctype='C' AND cohist_ordernumber=_p.cmhead_number);

--  Delete the Invoice aropen item
  DELETE FROM aropen
  WHERE (aropen_doctype='C' AND aropen_docnumber=_p.cmhead_number);

-- Handle the Inventory and G/L Transactions for any returned Inventory where cmitem_updateinv is true (reverse sense)
  FOR _r IN SELECT cmitem_itemsite_id AS itemsite_id, cmitem_id,
                   (cmitem_qtyreturned * cmitem_qty_invuomratio) AS qty,
                   cmhead_number, cmhead_cust_id AS cust_id, item_number,
                   cmhead_prj_id AS prj_id, cmhead_saletype_id AS saletype_id,
                   cmhead_shipzone_id AS shipzone_id
            FROM cmhead, cmitem, itemsite, item
            WHERE ( (cmitem_cmhead_id=cmhead_id)
             AND (cmitem_itemsite_id=itemsite_id)
             AND (itemsite_item_id=item_id)
             AND (cmitem_qtyreturned <> 0)
             AND (cmitem_updateinv)
             AND (cmhead_id=_p.cmhead_id) ) LOOP

--  Return credited stock to inventory
    IF (_itemlocSeries = 0) THEN
      SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
    END IF;
    SELECT postInvTrans( itemsite_id, 'RS', (_r.qty * -1),
                         'S/O', 'CM', _r.cmhead_number, '',
                         ('Credit Voided ' || _r.item_number),
                         costcat_asset_accnt_id,
                         getPrjAccntId(_r.prj_id, resolveCOSAccount(itemsite_id, _r.cust_id, _r.saletype_id, _r.shipzone_id)),  
                         _itemlocSeries, _glDate) INTO _invhistid
    FROM itemsite, costcat
    WHERE ( (itemsite_costcat_id=costcat_id)
     AND (itemsite_id=_r.itemsite_id) );

  END LOOP;

--  Update coitem to reflect the returned qty where cmitem_updateinv is true (reverse sense)
  FOR _r IN SELECT cmitem_qtyreturned, cmitem_itemsite_id, cohead_id
            FROM cmitem, cmhead, invchead, cohead
            WHERE ( (cmitem_cmhead_id=cmhead_id)
             AND (cmhead_invcnumber=invchead_invcnumber)
             AND (invchead_ordernumber=cohead_number)
             AND (cmitem_qtyreturned <> 0)
             AND (cmitem_updateinv)
             AND (cmhead_id=_p.cmhead_id) ) LOOP
    UPDATE coitem
    SET coitem_qtyreturned = (coitem_qtyreturned + (_r.cmitem_qtyreturned * -1.0))
    WHERE coitem_id IN ( SELECT coitem_id
                         FROM coitem
                         WHERE ( (coitem_cohead_id=_r.cohead_id)
                          AND (coitem_itemsite_id = _r.cmitem_itemsite_id) )
                         LIMIT 1 );
  END LOOP;

--  Mark the cmhead as voided
  UPDATE cmhead
  SET cmhead_void=TRUE
  WHERE (cmhead_id=_p.cmhead_id);

  RETURN _itemlocSeries;

END;

Function: public.voidinvoice(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pInvcheadid ALIAS FOR $1;
  _glSequence INTEGER := 0;
  _glJournal INTEGER := 0;
  _itemlocSeries INTEGER := 0;
  _aropenid INTEGER := 0;
  _invhistid INTEGER := 0;
  _amount NUMERIC;
  _roundedBase NUMERIC;
  _r RECORD;
  _p RECORD;
  _n RECORD;
  _test INTEGER;
  _totalAmount          NUMERIC := 0;
  _totalRoundedBase     NUMERIC := 0;
  _totalAmountBase      NUMERIC := 0;
  _appliedAmount        NUMERIC := 0;
  _commissionDue        NUMERIC := 0;
  _tmpAccntId INTEGER;
  _tmpCurrId  INTEGER;
  _firstExchDate        DATE;
  _glDate		DATE;
  _exchGain             NUMERIC := 0;

BEGIN

--  Cache Invoice information
  SELECT invchead.*,
         findFreightAccount(invchead_cust_id) AS freightaccntid,
         findARAccount(invchead_cust_id) AS araccntid,
         aropen_id,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM invcheadtax
           WHERE ( (taxhist_parent_id = invchead_id)
             AND   (taxhist_taxtype_id = getFreightTaxtypeId()) ) ) AS freighttax,
         ( SELECT COALESCE(SUM(taxhist_tax), 0)
           FROM invcheadtax
           WHERE ( (taxhist_parent_id = invchead_id)
             AND   (taxhist_taxtype_id = getAdjustmentTaxtypeId()) ) ) AS adjtax
       INTO _p 
  FROM invchead JOIN aropen ON (aropen_doctype='I' AND aropen_docnumber=invchead_invcnumber)
  WHERE (invchead_id=pInvcheadid);
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Invoice as invchead not found';
  END IF;
  IF (NOT _p.invchead_posted) THEN
    RETURN -10;
  END IF;

--  Cache AROpen Information
  SELECT aropen.* INTO _n
  FROM aropen
  WHERE ( (aropen_doctype='I')
    AND   (aropen_docnumber=_p.invchead_invcnumber) );
  IF (NOT FOUND) THEN
    RAISE EXCEPTION 'Cannot Void Invoice as aropen not found';
  END IF;

--  Check for ARApplications
  SELECT arapply_id INTO _test
  FROM arapply
  WHERE (arapply_target_aropen_id=_n.aropen_id)
  LIMIT 1;
  IF (FOUND) THEN
    RETURN -20;
  END IF;

  SELECT fetchGLSequence() INTO _glSequence;
  SELECT fetchJournalNumber('AR-IN') INTO _glJournal;

  _glDate := COALESCE(_p.invchead_gldistdate, _p.invchead_invcdate);

-- the 1st MC iteration used the cohead_orderdate so we could get curr exch
-- gain/loss between the sales and invoice dates, but see issue 3892.  leave
-- this condition TRUE until we make this configurable or decide not to.
  IF TRUE THEN
      _firstExchDate := _p.invchead_invcdate;
  ELSE
-- can we save a select by using: _firstExchDate := _p.invchead_orderdate;
      SELECT cohead_orderdate INTO _firstExchDate
      FROM cohead
      WHERE (cohead_number = _p.invchead_ordernumber);
  END IF;

--  Start by handling taxes (reverse sense)
  FOR _r IN SELECT tax_sales_accnt_id, 
              round(sum(taxdetail_tax),2) AS tax,
              currToBase(_p.invchead_curr_id, round(sum(taxdetail_tax),2), _firstExchDate) AS taxbasevalue
            FROM tax 
             JOIN calculateTaxDetailSummary('I', _p.invchead_id, 'T') ON (taxdetail_tax_id=tax_id)
	    GROUP BY tax_id, tax_sales_accnt_id LOOP

    PERFORM insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                _r.tax_sales_accnt_id, 
                                (_r.taxbasevalue * -1.0),
                                _glDate, ('Void-' || _p.invchead_billto_name) );

    _totalAmount := _totalAmount + _r.tax;
    _totalRoundedBase := _totalRoundedBase + _r.taxbasevalue;  
  END LOOP;

--  March through the Non-Misc. Invcitems
  FOR _r IN SELECT *
            FROM invoiceitem
            WHERE ( (invcitem_invchead_id = _p.invchead_id)
              AND   (invcitem_item_id <> -1) ) LOOP

--  Cache the amount due for this line
    _amount := _r.extprice;

    IF (_amount > 0) THEN
--  Credit the Sales Account for the invcitem item (reverse sense)
      IF (_r.itemsite_id IS NULL) THEN
	SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
	INTO _tmpAccntId
	FROM salesaccnt
	WHERE (salesaccnt_id=findSalesAccnt(_r.invcitem_item_id, 'I', _p.invchead_cust_id,
                                            _p.invchead_saletype_id, _p.invchead_shipzone_id));
      ELSE
	SELECT getPrjAccntId(_p.invchead_prj_id, salesaccnt_sales_accnt_id) 
	INTO _tmpAccntId
	FROM salesaccnt
	WHERE (salesaccnt_id=findSalesAccnt(_r.itemsite_id, 'IS', _p.invchead_cust_id,
                                            _p.invchead_saletype_id, _p.invchead_shipzone_id));
      END IF;

--  If the Sales Account Assignment was not found then punt
      IF (NOT FOUND) THEN
        PERFORM deleteGLSeries(_glSequence);
        RETURN -11;
      END IF;

      _roundedBase := round(currToBase(_p.invchead_curr_id, _amount, _firstExchDate), 2);
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 _tmpAccntId,
                                 (_roundedBase * -1.0),
                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;

      _totalAmount := (_totalAmount + _amount);
      _totalRoundedBase := _totalRoundedBase + _roundedBase;
      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
    END IF;

    _totalAmount := _totalAmount;
    _totalRoundedBase := _totalRoundedBase;

  END LOOP;

--  March through the Misc. Invcitems
  FOR _r IN SELECT *
            FROM invoiceitem JOIN salescat ON (salescat_id = invcitem_salescat_id)
            WHERE ( (invcitem_item_id = -1)
              AND   (invcitem_invchead_id=_p.invchead_id) ) LOOP

--  Cache the amount due for this line and the commission due for such
    _amount := _r.extprice;

    IF (_amount > 0) THEN
--  Credit the Sales Account for the invcitem item (reverse sense)
      _roundedBase = round(currToBase(_p.invchead_curr_id, _amount,
                                      _firstExchDate), 2);
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 getPrjAccntId(_p.invchead_prj_id, _r.salescat_sales_accnt_id), 
                                 (_roundedBase * -1.0),
                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;

      IF (_test < 0) THEN
        PERFORM deleteGLSeries(_glSequence);
        RETURN _test;
      END IF;

      _totalAmount := (_totalAmount + _amount);
      _totalRoundedBase :=  _totalRoundedBase + _roundedBase;
      _commissionDue := (_commissionDue + (_amount * _p.invchead_commission));
    END IF;

  END LOOP;

--  Credit the Freight Account for Freight Charges (reverse sense)
  IF (_p.invchead_freight <> 0) THEN
    IF (_p.freightaccntid <> -1) THEN
      _roundedBase = round(currToBase(_p.invchead_curr_id, _p.invchead_freight,
                                      _firstExchDate), 2);
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 getPrjAccntId(_p.invchead_prj_id,_p.freightaccntid), 
                                 (_roundedBase * -1.0),
                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;

--  Cache the Freight Amount distributed
        _totalAmount := (_totalAmount + _p.invchead_freight);
        _totalRoundedBase := _totalRoundedBase + _roundedBase;
    ELSE
      _test := -14;
    END IF;

--  If the Freight Account was not found then punt
    IF (_test < 0) THEN
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;

  END IF;

--  Credit the Misc. Account for Miscellaneous Charges (reverse sense)
  IF (_p.invchead_misc_amount <> 0) THEN
    _roundedBase := round(currToBase(_p.invchead_curr_id, _p.invchead_misc_amount,
                                     _firstExchDate), 2);
    SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                               getPrjAccntId(_p.invchead_prj_id, _p.invchead_misc_accnt_id), 
                               (_roundedBase * -1.0),
                               _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;

--  If the Misc. Charges Account was not found then punt
    IF (_test < 0) THEN
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;

--  Cache the Misc. Amount distributed
    _totalAmount := (_totalAmount + _p.invchead_misc_amount);
    _totalRoundedBase := _totalRoundedBase + _roundedBase;

  END IF;

-- ToDo: handle rounding errors (reverse sense)
    _exchGain := currGain(_p.invchead_curr_id, _totalAmount,
                          _firstExchDate, _glDate);
    IF (_exchGain <> 0) THEN
        SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                   getGainLossAccntId(_p.araccntid),
                                   round(_exchGain, 2),
                                   _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test ;
        IF (_test < 0) THEN
          PERFORM deleteGLSeries(_glSequence);
          RETURN _test;
        END IF;
    END IF;

--  Debit A/R for the total Amount (reverse sense)
  IF (_totalRoundedBase <> 0) THEN
    IF (_p.araccntid != -1) THEN
      SELECT insertIntoGLSeries( _glSequence, 'A/R', 'IN', _p.invchead_invcnumber,
                                 _p.araccntid,
                                 round(_totalRoundedBase, 2),
                                 _glDate, ('Void-' || _p.invchead_billto_name) ) INTO _test;
    ELSE
      PERFORM deleteGLSeries(_glSequence);
      RETURN _test;
    END IF;
  END IF;

--  Commit the GLSeries;
  SELECT postGLSeries(_glSequence, _glJournal) INTO _test;
  IF (_test < 0) THEN
    PERFORM deleteGLSeries(_glSequence);
    RETURN _test;
  END IF;

--  Delete sales history
  DELETE FROM cohisttax
  WHERE (taxhist_parent_id IN (SELECT cohist_id
                               FROM cohist
                               WHERE (cohist_doctype='I' AND cohist_invcnumber=_p.invchead_invcnumber)));

  DELETE FROM cohist
  WHERE (cohist_doctype='I' AND cohist_invcnumber=_p.invchead_invcnumber);

--  Create the Credit aropen item
  SELECT nextval('aropen_aropen_id_seq') INTO _aropenid;
  INSERT INTO aropen
  ( aropen_id, aropen_username, aropen_journalnumber,
    aropen_open, aropen_posted,
    aropen_cust_id, aropen_ponumber,
    aropen_docnumber, aropen_applyto, aropen_doctype,
    aropen_docdate, aropen_duedate, aropen_distdate, aropen_terms_id,
    aropen_amount, aropen_paid,
    aropen_salesrep_id, aropen_commission_due, aropen_commission_paid,
    aropen_ordernumber, aropen_notes, aropen_cobmisc_id,
    aropen_curr_id )
  VALUES
  ( _aropenid, getEffectiveXtUser(), _glJournal,
    TRUE, FALSE,
    _p.invchead_cust_id, _p.invchead_ponumber,
    _p.invchead_invcnumber, _p.invchead_invcnumber, 'C',
    _p.invchead_invcdate, determineDueDate(_p.invchead_terms_id, _p.invchead_invcdate), _glDate, _p.invchead_terms_id,
    round(_totalAmount, 2), round(_totalAmount, 2), 
    _p.invchead_salesrep_id, _commissionDue, FALSE,
    _p.invchead_ordernumber::text, _p.invchead_notes, pInvcheadid,
    _p.invchead_curr_id );

--  Alter the Invoice A/R Open Item to reflect the application
    UPDATE aropen
    SET aropen_paid = round(_totalAmount, 2)
    WHERE (aropen_id=_p.aropen_id);

--  Record the application
    INSERT INTO arapply
    ( arapply_cust_id,
      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
      arapply_fundstype, arapply_refnumber,
      arapply_applied, arapply_closed,
      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_curr_id )
    VALUES
    ( _p.invchead_cust_id,
      _aropenid, 'C', _p.invchead_invcnumber,
      _p.aropen_id, 'I', _p.invchead_invcnumber,
      '', '',
      round(_totalAmount, 2), TRUE,
      CURRENT_DATE, _p.invchead_invcdate, 0, _p.invchead_curr_id );

-- Handle the Inventory and G/L Transactions for any billed Inventory where invcitem_updateinv is true (reverse sense)
  FOR _r IN SELECT itemsite_id AS itemsite_id, invcitem_id,
                   (invcitem_billed * invcitem_qty_invuomratio) AS qty,
                   invchead_invcnumber, invchead_cust_id AS cust_id, item_number,
                   invchead_prj_id AS prj_id, invchead_saletype_id AS saletype_id,
                   invchead_shipzone_id AS shipzone_id
            FROM invchead JOIN invcitem ON ( (invcitem_invchead_id=invchead_id) AND
                                             (invcitem_billed <> 0) AND
                                             (invcitem_updateinv) )
                          JOIN itemsite ON ( (itemsite_item_id=invcitem_item_id) AND
                                             (itemsite_warehous_id=invcitem_warehous_id) )
                          JOIN item ON (item_id=invcitem_item_id)
            WHERE (invchead_id=_p.invchead_id) LOOP

--  Issue billed stock from inventory
    IF (_itemlocSeries = 0) THEN
      SELECT NEXTVAL('itemloc_series_seq') INTO _itemlocSeries;
    END IF;
    SELECT postInvTrans( itemsite_id, 'SH', (_r.qty * -1.0),
                         'S/O', 'IN', _r.invchead_invcnumber, '',
                         ('Invoice Voided ' || _r.item_number),
                         getPrjAccntId(_r.prj_id, resolveCOSAccount(itemsite_id, _r.cust_id, _r.saletype_id, _r.shipzone_id)),
                         costcat_asset_accnt_id, _itemlocSeries, _glDate) INTO _invhistid
    FROM itemsite, costcat
    WHERE ( (itemsite_costcat_id=costcat_id)
     AND (itemsite_id=_r.itemsite_id) );

  END LOOP;

--  Reopen Billing
  UPDATE shipitem
  SET shipitem_invoiced=FALSE,
      shipitem_invcitem_id=NULL
  WHERE (shipitem_invcitem_id IN (SELECT invcitem_id
                                  FROM invcitem
                                  WHERE (invcitem_invchead_id=_p.invchead_id)));
  UPDATE cobill
  SET cobill_invcnum=NULL,
      cobill_invcitem_id=NULL
  WHERE (cobill_invcitem_id IN (SELECT invcitem_id
                                FROM invcitem
                                WHERE (invcitem_invchead_id=_p.invchead_id)));
  UPDATE cobmisc
  SET cobmisc_posted=FALSE,
      cobmisc_invcnumber=NULL,
      cobmisc_invchead_id=NULL
  WHERE (cobmisc_invchead_id=_p.invchead_id);

--  Mark the invoice as voided
  UPDATE invchead
  SET invchead_void=TRUE,
      invchead_notes=(invchead_notes || 'Voided on ' || current_date || ' by ' || getEffectiveXtUser())
  WHERE (invchead_id=_p.invchead_id);
 
  RETURN _itemlocSeries;

END;

Function: public.voidpostedapcheck(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'voidPostedAPCheck() is deprecated - use voidPostedCheck() instead';
  RETURN voidPostedCheck($1, fetchJournalNumber('AP-CK'), CURRENT_DATE);
END;

Function: public.voidpostedapcheck(integer, integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'voidPostedAPCheck() is deprecated - use voidPostedCheck() instead';
  RETURN voidPostedCheck($1, $2, CURRENT_DATE);
END;

Function: public.voidpostedapcheck(integer, integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  RAISE NOTICE 'voidPostedAPCheck() is deprecated - use voidPostedCheck() instead';
  RETURN voidPostedCheck($1, $2, $3);
END;

Function: public.voidpostedcheck(integer, integer, date)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pCheckid		ALIAS FOR $1;
  pJournalNumber	ALIAS FOR $2;
  pVoidDate		ALIAS FOR $3;
  _amount_base		NUMERIC := 0;
  _result               INTEGER;
  _apopenid		INTEGER;
  _credit_glaccnt	INTEGER;
  _docnumber		TEXT;
  _exchGain		NUMERIC := 0;
  _exchGainTmp		NUMERIC := 0;
  _gltransNote		TEXT;
  _p			RECORD;
  _r			RECORD;
  _sequence		INTEGER;
  _amount_check         NUMERIC := 0;

BEGIN

  SELECT fetchGLSequence() INTO _sequence;

  SELECT checkhead.*,
         checkhead_amount / checkhead_curr_rate AS checkhead_amount_base,
         bankaccnt_accnt_id AS bankaccntid,
         findPrepaidAccount(checkhead_recip_id) AS prepaidaccntid,
	 checkrecip.* INTO _p
  FROM bankaccnt, checkhead LEFT OUTER JOIN
       checkrecip ON ((checkrecip_type=checkhead_recip_type)
		  AND (checkrecip_id=checkhead_recip_id))
  WHERE ((checkhead_bankaccnt_id=bankaccnt_id)
    AND  (checkhead_id=pCheckid));

  IF (NOT _p.checkhead_posted) THEN
    RETURN -10;
  END IF;

  IF (_p.checkrecip_id IS NULL) THEN	-- outer join failed
    RETURN -11;
  END IF;

  -- Cannot void if already reconciled
  SELECT trans_id INTO _result
  FROM ( SELECT gltrans_id AS trans_id
         FROM gltrans
         WHERE ((gltrans_doctype='CK')
           AND  (gltrans_misc_id=_p.checkhead_id)
           AND  (gltrans_rec))
         UNION ALL
         SELECT sltrans_id AS trans_id
         FROM sltrans
         WHERE ((sltrans_doctype='CK')
           AND  (sltrans_misc_id=_p.checkhead_id)
           AND  (sltrans_rec)) ) AS data;
  IF (FOUND) THEN
    RETURN -14;
  END IF;

  _gltransNote := 'Void Posted Check #' || _p.checkhead_number || ' ' ||
		  _p.checkrecip_number || '-' || _p.checkrecip_name;

  IF (_p.checkhead_misc) THEN
    IF (COALESCE(_p.checkhead_expcat_id, -1) < 0) THEN
      IF (_p.checkhead_recip_type = 'V') THEN
	PERFORM createAPDebitMemo(_p.checkhead_recip_id, pJournalNumber,
				  CAST(fetchAPMemoNumber() AS text), '',
				  pVoidDate, _p.checkhead_amount,
				  _gltransNote || ' '|| _p.checkhead_notes,
				  -1, pVoidDate, -1, _p.checkhead_curr_id );
	_credit_glaccnt := findAPPrepaidAccount(_p.checkhead_recip_id);

      ELSIF (_p.checkhead_recip_type = 'C') THEN
	PERFORM createARCreditMemo(NULL, _p.checkhead_recip_id,
				  fetchARMemoNumber(), '', 
				  pVoidDate, _p.checkhead_amount,
				  _gltransNote || ' '|| _p.checkhead_notes,
				  -1, -1, -1, pVoidDate, -1, NULL, 0.0,
				  pJournalNumber, _p.checkhead_curr_id );
	_credit_glaccnt := _p.prepaidaccntid;

      ELSIF (_p.checkhead_recip_type = 'T') THEN
	-- TODO: should we create a debit memo for the tax authority? how?
	_credit_glaccnt := _p.checkrecip_accnt_id;

      END IF; -- recip type

    ELSE
      SELECT expcat_exp_accnt_id INTO _credit_glaccnt
      FROM expcat
      WHERE (expcat_id=_p.checkhead_expcat_id);
      IF (NOT FOUND) THEN
        RETURN -12;
      END IF;
    END IF;

    IF (COALESCE(_credit_glaccnt, -1) < 0) THEN
      RETURN -13;
    END IF;

    PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source, 'CK',
				text(_p.checkhead_number),
				_credit_glaccnt,
				round(_p.checkhead_amount_base, 2),
				pVoidDate, _gltransNote, pCheckid);

    _amount_base := _p.checkhead_amount_base;

  ELSE
    FOR _r IN SELECT checkitem_amount, checkitem_discount,
                     CASE WHEN (checkitem_apopen_id IS NOT NULL) THEN
                       checkitem_amount / apopen_curr_rate
                     ELSE
                       currToBase(checkitem_curr_id,
                                  checkitem_amount,
                                  COALESCE(checkitem_docdate, _p.checkhead_checkdate)) 
                     END AS checkitem_amount_base,
                       checkitem_amount / checkitem_curr_rate	 AS amount_check,
                     apopen_id, apopen_doctype, apopen_docnumber, apopen_curr_rate, apopen_docdate,
                     aropen_id, aropen_doctype, aropen_docnumber,
                     checkitem_curr_id, checkitem_curr_rate,
                     COALESCE(checkitem_docdate, _p.checkhead_checkdate) AS docdate
              FROM (checkitem LEFT OUTER JOIN
		    apopen ON (checkitem_apopen_id=apopen_id)) LEFT OUTER JOIN
		    aropen ON (checkitem_aropen_id=aropen_id)
              WHERE (checkitem_checkhead_id=pcheckid) LOOP

      _exchGainTmp := 0;
      IF (_r.apopen_id IS NOT NULL) THEN
	-- undo the APDiscount Credit Memo if a discount was taken
        IF(_r.checkitem_discount > 0) THEN
          SELECT NEXTVAL('apopen_apopen_id_seq') INTO _apopenid;
          SELECT fetchAPMemoNumber() INTO _docnumber;
          INSERT INTO apopen
          ( apopen_id, apopen_username, apopen_journalnumber,
            apopen_vend_id, apopen_docnumber, apopen_doctype, apopen_ponumber,
            apopen_docdate, apopen_duedate, apopen_distdate, apopen_terms_id,
            apopen_amount, apopen_paid, apopen_open,
	    apopen_notes,
	    apopen_accnt_id, apopen_curr_id, apopen_discount, apopen_curr_rate,
            apopen_closedate )
          VALUES
          ( _apopenid, getEffectiveXtUser(), pJournalNumber,
            _p.checkhead_recip_id, _docnumber, 'D', '',
            pVoidDate, pVoidDate, pVoidDate, -1,
            _r.checkitem_discount, _r.checkitem_discount, FALSE,
            ('Reverse Posted Discount ' || _r.apopen_doctype || ' ' ||
	      _r.apopen_docnumber),
	    -1, _p.checkhead_curr_id, TRUE, _r.apopen_curr_rate,
            current_date );


          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
				      'DS', _r.apopen_docnumber,
                                      findAPDiscountAccount(_p.checkhead_recip_id),
                                      round(_r.checkitem_discount / _r.apopen_curr_rate, 2) * -1,
                                      pVoidDate, _gltransNote, pCheckid);

          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
				      'DS', _r.apopen_docnumber,
                                      findAPAccount(_p.checkhead_recip_id),
                                      round(_r.checkitem_discount / _r.apopen_curr_rate, 2),
                                      pVoidDate, _gltransNote, pCheckid);

	  --  Post the application
          INSERT INTO apapply
          ( apapply_vend_id, apapply_postdate, apapply_username,
            apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
            apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
            apapply_journalnumber, apapply_amount, apapply_curr_id )
          VALUES
          ( _p.checkhead_recip_id, pVoidDate, getEffectiveXtUser(),
            _apopenid, 'D', _docnumber,
            _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
            pJournalNumber, (_r.checkitem_discount * -1), _r.checkitem_curr_id );
        END IF; -- discount was taken

        UPDATE apopen
       SET apopen_paid = round(apopen_paid -
				(_r.checkitem_amount + noNeg(_r.checkitem_discount)), 2),
            apopen_open = round(apopen_amount, 2) >
			  round(apopen_paid -
				(_r.checkitem_amount + noNeg(_r.checkitem_discount)), 2),
            apopen_closedate = CASE WHEN (round(apopen_amount, 2) >
			                  round(apopen_paid -
				           (_r.checkitem_amount + noNeg(_r.checkitem_discount)))) THEN NULL ELSE apopen_closedate END
        WHERE (apopen_id=_r.apopen_id);

	--  Post the application
        INSERT INTO apapply
        ( apapply_vend_id, apapply_postdate, apapply_username,
          apapply_source_apopen_id, apapply_source_doctype, apapply_source_docnumber,
          apapply_target_apopen_id, apapply_target_doctype, apapply_target_docnumber,
          apapply_journalnumber, apapply_amount, apapply_curr_id )
        VALUES
        ( _p.checkhead_recip_id, pVoidDate, getEffectiveXtUser(),
          -1, 'K', _p.checkhead_number,
          _r.apopen_id, _r.apopen_doctype, _r.apopen_docnumber,
          pJournalNumber, (_r.checkitem_amount * -1), _r.checkitem_curr_id );
      END IF; -- if check item's apopen_id is not null

      IF (_r.aropen_id IS NOT NULL) THEN
        UPDATE aropen
        SET aropen_paid = round(aropen_paid -_r.checkitem_amount, 2),
            aropen_open = round(aropen_amount, 2) >
			  round(aropen_paid - _r.checkitem_amount, 2)
        WHERE (aropen_id=_r.aropen_id);

	--  Post the application
        INSERT INTO arapply
        ( arapply_cust_id, arapply_postdate, arapply_distdate, arapply_username,
          arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
          arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
          arapply_journalnumber, arapply_applied, arapply_curr_id )
        VALUES
        ( _p.checkhead_recip_id, pVoidDate, pVoidDate, getEffectiveXtUser(),
          -1, 'K', _p.checkhead_number,
          _r.aropen_id, _r.aropen_doctype, _r.aropen_docnumber,
          pJournalNumber, (_r.checkitem_amount * -1), _r.checkitem_curr_id );

      END IF; -- if check item's aropen_id is not null

--  calculate currency gain/loss
      IF (_r.apopen_id IS NOT NULL) THEN
      	IF (_r.apopen_docdate > _p.checkhead_checkdate) THEN
	  _exchGainTmp := ((_r.checkitem_amount/_p.checkhead_currrate) - (_r.checkitem_amount / _r.apopen_curr_rate)) * -1;
	ELSE
          _exchGainTmp := ((_r.checkitem_amount / _r.apopen_curr_rate) - (_r.checkitem_amount/_p.checkhead_curr_rate));
	END IF;
      ELSIF (_r.aropen_id IS NOT NULL) THEN
        SELECT arCurrGain(_r.aropen_id,_r.checkitem_curr_id, _r.checkitem_amount,
                        _p.checkhead_checkdate)
              INTO _exchGainTmp;
      END IF;
      _exchGain := _exchGain + _exchGainTmp;

      PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
				  'CK', text(_p.checkhead_number),
                                  _p.checkrecip_accnt_id,
                                  round(_r.checkitem_amount_base, 2),
                                  pVoidDate, _gltransNote, pCheckid);
      IF (_exchGainTmp <> 0) THEN
          PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
				      'CK', text(_p.checkhead_number),
				      getGainLossAccntId(_p.checkrecip_accnt_id),
				      round(_exchGainTmp, 2) * -1,
				      pVoidDate, _gltransNote, pCheckid);
      END IF;

      _amount_check := (_amount_check + _r.amount_check);
      _amount_base := (_amount_base + _r.checkitem_amount_base);

    END LOOP;

    IF( (_amount_check - _p.checkhead_amount) <> 0.0 ) THEN 
      _exchGainTmp :=  (_amount_check - _p.checkhead_amount) / _p.checkhead_curr_rate;
      _exchGain := _exchGain + _exchGainTmp;
    END IF;

    --  ensure that the check balances, attribute rounding errors to gain/loss
    IF round(_amount_base, 2) - round(_exchGain, 2) <> round(_p.checkhead_amount_base, 2) THEN
      IF round(_amount_base - _exchGain, 2) = round(_p.checkhead_amount_base, 2) THEN
	PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source,
				    'CK',
				    text(_p.checkhead_number), getGainLossAccntId(_p.bankaccntid),
				    (round(_amount_base, 2) -
				     round(_exchGain, 2) -
				     round(_p.checkhead_amount_base, 2)) * -1,
				    pVoidDate, _gltransNote, pCheckid);
      ELSE
	RAISE EXCEPTION 'checkhead_id % does not balance (% - % <> %)', pCheckid,
	      _amount_base, _exchGain, _p.checkhead_amount_base;
      END IF;
    END IF;
  END IF;

  PERFORM insertIntoGLSeries( _sequence, _p.checkrecip_gltrans_source, 'CK',
			      text(_p.checkhead_number),
                              _p.bankaccntid,
			      round(_p.checkhead_amount_base, 2) * -1,
                              pVoidDate, _gltransNote, pCheckid);

  PERFORM postGLSeries(_sequence, pJournalNumber);

  UPDATE gltrans
     SET gltrans_misc_id=pCheckid
   WHERE gltrans_sequence=_sequence;

  UPDATE checkhead
  SET checkhead_posted=false,
      checkhead_void=true,
      checkhead_journalnumber=pJournalNumber
  WHERE (checkhead_id=pCheckid);

  RETURN pJournalNumber;

END;

Function: public.woeffectivedate(date)

Returns: date

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pStartDate ALIAS FOR $1;

BEGIN

  IF (explodeWoEffective() = 'E') THEN
    RETURN CURRENT_DATE;
  ELSE
    RETURN pStartDate;
  END IF;

END;

Function: public.woinvavail(integer, boolean, boolean, boolean, boolean)

Returns: SET OF woinvav

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;   
   pshowchildindent ALIAS FOR $2;    
   pshowchildsum ALIAS FOR $3;
   pshowshortage ALIAS FOR $4;
   pshowlowinventory ALIAS FOR $5;
  _row woinvav%ROWTYPE;
  _subrow woinvav%ROWTYPE;
  _wonumber TEXT;
  _x RECORD;
  _subx RECORD;  
  _qry TEXT;
   
BEGIN   
    
    IF(pshowchildindent) THEN 
      --get top level order   
      FOR _x IN
          SELECT wo_id,
                itemsite_id,
                item_type,
                wo_number,
                wo_subnumber,                             
                item_number,
                item_descrip1, 
                item_descrip2, 
                uom_name,
                qoh, 
                wobalance, 
                allocated, 
                ordered,                        
                reorderlevel,
                (qoh + ordered - wobalance) AS woavail,
                (qoh + ordered - allocated) AS totalavail 
         FROM(SELECT wo_id,
                itemsite_id,
                item_type,
                wo_number,
                wo_subnumber,                             
                item_number,
                item_descrip1, 
                item_descrip2, 
                uom_name,
                noNeg(itemsite_qtyonhand) AS qoh, 
                noNeg(wo_qtyord - wo_qtyrcv) AS wobalance, 
                qtyAllocated(itemsite_id, wo_duedate) AS allocated, 
                qtyOrdered(itemsite_id, wo_duedate) AS ordered,                        
                CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel 
          FROM wo, itemsite, item, uom     
         WHERE ((wo_id = pwoid)          
           AND (itemsite_id = wo_itemsite_id)
           AND (itemsite_item_id=item_id)
           AND (item_inv_uom_id=uom_id))               
         ORDER BY wo_number, wo_subnumber) AS data
       LOOP       
         _row.woinvav_itemsite_id := _x.itemsite_id;            
         _row.woinvav_womatl_id := -1;
         _row.woinvav_type := _x.item_type;          
         _row.woinvav_item_wo_number := _x.wo_number || '-' || _x.wo_subnumber;
         _row.woinvav_descrip := _x.item_descrip1 || ' ' || _x.item_descrip2;
         _row.woinvav_uomname := _x.uom_name;
         _row.woinvav_qoh := _x.qoh;
         _row.woinvav_balance := _x.wobalance;
         _row.woinvav_allocated := _x.allocated;     
         _row.woinvav_ordered := _x.ordered;         
         _row.woinvav_woavail := _x.woavail;
         _row.woinvav_totalavail := _x.totalavail;
         _row.woinvav_reorderlevel := _x.reorderlevel;
         _row.woinvav_level := 0;                       
         RETURN NEXT _row;                
        --get materials for this level        
        FOR _subx IN
          SELECT * FROM woinvavailmatl(_x.wo_id, 1, pshowshortage, pshowlowinventory) 
        LOOP                                            
	  RETURN NEXT _subx;
	END LOOP;  
	FOR _subx IN
          SELECT * FROM woinvavail(_x.wo_id, 1, pshowshortage, pshowlowinventory)
        LOOP                                            
	  RETURN NEXT _subx;
	END LOOP;  
     END LOOP;             
    ELSE
       SELECT wo_number FROM wo WHERE wo_id=pwoid LIMIT 1 INTO _wonumber;   
       --display a single level sum of work order requirements
       _qry := 'SELECT  wo_id,
                        itemsite_id, 
		        womatl_id,
			item_type,
			wo_number,                         
                        item_number, 
                        item_descrip1, 
                        item_descrip2, 
                        uom_name,                         
                        qoh, 
                        wobalance, 
                        allocated, 
                        ordered,                        
                        reorderlevel,
                        (qoh + ordered - wobalance) AS woavail,
                        (qoh + ordered - allocated) AS totalavail
	          FROM (SELECT wo_id,
	                itemsite_id, 
			womatl_id,
			item_type,			
			wo_number,                         
                        item_number, 
                        item_descrip1, 
                        item_descrip2, 
                        uom_name,                         
                        noNeg(itemsite_qtyonhand) AS qoh, 
                        noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss)) AS wobalance, 
                        qtyAllocated(itemsite_id, womatl_duedate) AS allocated, 
                        qtyOrdered(itemsite_id, womatl_duedate) AS ordered,                        
                        CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel 
                   FROM wo, womatl, itemsite, item, uom  
                 WHERE (womatl_wo_id=wo_id) 
                   AND (womatl_itemsite_id=itemsite_id) 
                   AND (itemsite_item_id=item_id) 
                   AND (item_inv_uom_id=uom_id) ';
                IF(pshowchildsum) THEN
                  _qry := _qry || ' AND (wo_number=' || _wonumber || ')';
                ELSE  
                  _qry := _qry || ' AND (womatl_wo_id=' || pwoid || ')';                  
                END IF; 
                 _qry := _qry || ' ORDER BY item_number) AS data ';  
                IF(pshowshortage) THEN
                  _qry := _qry || ' WHERE (((qoh + ordered - allocated) < 0) OR ((qoh + ordered - wobalance) < 0)) '; 
                END IF;
                IF(pshowlowinventory AND NOT pshowshortage) THEN                 
                  _qry := _qry || ' WHERE (((qoh - allocated) < 0) OR ((qoh - wobalance) < 0)) '; 
                END IF;                 
                
      FOR _x IN   
         EXECUTE _qry
      LOOP        
        _row.woinvav_itemsite_id := _x.itemsite_id;            
        _row.woinvav_womatl_id := _x.womatl_id;  
        _row.woinvav_type := _x.item_type;      
        _row.woinvav_item_wo_number := _x.item_number;
        _row.woinvav_descrip := _x.item_descrip1 || ' ' || _x.item_descrip2;
        _row.woinvav_uomname := _x.uom_name;
        _row.woinvav_qoh := _x.qoh;
        _row.woinvav_balance := _x.wobalance;
        _row.woinvav_allocated := _x.allocated;     
        _row.woinvav_ordered := _x.ordered;         
        _row.woinvav_woavail := _x.woavail;
        _row.woinvav_totalavail := _x.totalavail;
        _row.woinvav_reorderlevel := _x.reorderlevel;
        _row.woinvav_level := 0;                
        RETURN NEXT _row;  
  END LOOP;
  END IF;                     
  RETURN;
END;

Function: public.woinvavail(integer, integer, boolean, boolean)

Returns: SET OF woinvav

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1; 
   plevel ALIAS FOR $2;
   pshowshortage ALIAS FOR $3;
   pshowlowinventory ALIAS FOR $4;
  _row woinvav%ROWTYPE;
  _x RECORD;
  _subx RECORD;
  _index INTEGER;
  _level INTEGER;
  _qry TEXT;   
BEGIN   
    FOR _x IN
          SELECT wo_id,
                itemsite_id,
                item_type,
                wo_number,
                wo_subnumber,                             
                item_number,
                item_descrip1, 
                item_descrip2, 
                uom_name,
                qoh, 
                wobalance, 
                allocated, 
                ordered,                        
                reorderlevel,
                (qoh + ordered - wobalance) AS woavail,
                (qoh + ordered - allocated) AS totalavail 
         FROM(SELECT wo_id,
                itemsite_id,
                item_type,
                wo_number,
                wo_subnumber,                             
                item_number,
                item_descrip1, 
                item_descrip2, 
                uom_name,
                noNeg(itemsite_qtyonhand) AS qoh, 
                noNeg(wo_qtyord - wo_qtyrcv) AS wobalance, 
                qtyAllocated(itemsite_id, wo_duedate) AS allocated, 
                qtyOrdered(itemsite_id, wo_duedate) AS ordered,                        
                CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel 
          FROM wo, itemsite, item, uom     
         WHERE ((wo_ordid = pwoid)
           AND NOT (wo_status = 'C')          
           AND (itemsite_id = wo_itemsite_id)
           AND (itemsite_item_id=item_id)
           AND (item_inv_uom_id=uom_id))               
         ORDER BY wo_number, wo_subnumber) AS data
       LOOP       
         _row.woinvav_itemsite_id := _x.itemsite_id;            
         _row.woinvav_womatl_id := -1;
         _row.woinvav_type := _x.item_type;          
         _row.woinvav_item_wo_number := _x.wo_number || '-' || _x.wo_subnumber;
         _row.woinvav_descrip := _x.item_descrip1 || ' ' || _x.item_descrip2;
         _row.woinvav_uomname := _x.uom_name;
         _row.woinvav_qoh := _x.qoh;
         _row.woinvav_balance := _x.wobalance;
         _row.woinvav_allocated := _x.allocated;     
         _row.woinvav_ordered := _x.ordered;         
         _row.woinvav_woavail := _x.woavail;
         _row.woinvav_totalavail := _x.totalavail;
         _row.woinvav_reorderlevel := _x.reorderlevel;               
         _row.woinvav_level := plevel;                       
         RETURN NEXT _row;         
        --get materials for this level
        FOR _subx IN
          SELECT * FROM woinvavailmatl(_x.wo_id, plevel + 1, pshowshortage, pshowlowinventory) 
        LOOP                                            
	  RETURN NEXT _subx;
	END LOOP;
        --get next level wo
        FOR _subx IN
          SELECT * FROM woinvavail(_x.wo_id, plevel + 1, pshowshortage, pshowlowinventory) 
        LOOP                                            
	  RETURN NEXT _subx;
	END LOOP;
      END LOOP;   
  RETURN;
END;

Function: public.woinvavailmatl(integer, integer, boolean, boolean)

Returns: SET OF woinvav

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
   pwoid ALIAS FOR $1;    
   plevel ALIAS FOR $2;
   pshowshortage ALIAS FOR $3;
   pshowlowinventory ALIAS FOR $4;
  _subrow woinvav%ROWTYPE;  
  _subx RECORD;
  _qry TEXT;
BEGIN
  
   _qry := 'SELECT itemsite_id, 
           womatl_id,
           item_type, 
           wo_number, 
           wo_subnumber, 
           womatl_ref, 
           womatl_notes, 
           item_number,
           item_descrip1, 
           item_descrip2, 
           uom_name,
           qoh, 
           wobalance, 
           allocated, 
           ordered,
           (qoh + ordered - wobalance) AS woavail,
           (qoh + ordered - allocated) AS totalavail,
           reorderlevel 
    FROM(SELECT itemsite_id, 
                womatl_id,
                item_type,                 
                wo_number, 
                wo_subnumber, 
                womatl_ref, 
                womatl_notes, 
                item_number,
                item_descrip1, 
                item_descrip2, 
                uom_name,
                noNeg(itemsite_qtyonhand) AS qoh, 
                noNeg(itemuomtouom(itemsite_item_id, womatl_uom_id, NULL, womatl_qtyreq - womatl_qtyiss)) AS wobalance, 
                qtyAllocated(itemsite_id, womatl_duedate) AS allocated, 
                qtyOrdered(itemsite_id, womatl_duedate) AS ordered,
                CASE WHEN(itemsite_useparams) THEN itemsite_reorderlevel ELSE 0.0 END AS reorderlevel
    FROM womatl, wo, itemsite, item, uom
    WHERE ((wo_id = womatl_wo_id)     
     AND (womatl_itemsite_id = itemsite_id)
     AND (itemsite_item_id=item_id)
     AND (womatl_uom_id=uom_id)
     AND (NOT womatl_createwo OR womatl_createwo IS NULL))';
     _qry := _qry || ' AND (wo_id=' || pwoid || ') ORDER BY item_number) AS data';
     IF(pshowshortage) THEN
     _qry := _qry || ' WHERE (((qoh + ordered - allocated) < 0) OR ((qoh + ordered - wobalance) < 0)) '; 
     END IF;
     IF(pshowlowinventory AND NOT pshowshortage) THEN                 
     _qry := _qry || ' WHERE (((qoh - allocated) < 0) OR ((qoh - wobalance) < 0)) '; 
     END IF;
        
     
     
  FOR _subx IN
      EXECUTE _qry
  LOOP
     _subrow.woinvav_itemsite_id := _subx.itemsite_id;            
     _subrow.woinvav_womatl_id := _subx.womatl_id;
     _subrow.woinvav_type := _subx.item_type;            
     _subrow.woinvav_item_wo_number := _subx.item_number;
     _subrow.woinvav_descrip := _subx.item_descrip1 || ' ' || _subx.item_descrip2;
     _subrow.woinvav_uomname := _subx.uom_name;
     _subrow.woinvav_qoh := _subx.qoh;
     _subrow.woinvav_balance := _subx.wobalance;
     _subrow.woinvav_allocated := _subx.allocated;     
     _subrow.woinvav_ordered := _subx.ordered;         
     _subrow.woinvav_woavail := _subx.woavail;
     _subrow.woinvav_totalavail := _subx.totalavail;
     _subrow.woinvav_reorderlevel := _subx.reorderlevel;
     _subrow.woinvav_level := plevel;                                     
    RETURN NEXT _subrow; 
  END LOOP;            
  RETURN;
END;

Function: public.wostarted(pwoid integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _result BOOLEAN := FALSE;
   
BEGIN   
  -- is it really this simple?
  SELECT (wo_wipvalue > 0) INTO _result
    FROM wo
   WHERE wo_id=pWoid;
  
  RETURN COALESCE(_result, FALSE);
END;

Schema te

This file is part of the xTuple ERP: PostBooks Edition, a free and open source Enterprise Resource Planning software suite, Copyright (c) 1999-2010 by OpenMFG LLC, d/b/a xTuple. It is licensed to you under the Common Public Attribution License version 1.0, the full text of which (including xTuple-specific Exhibits) is available at www.xtuple.com/CPAL. By using this software, you agree to be bound by its terms.


Table: te.pkgcmd

te.pkgcmd Structure
F-Key Name Type Description
cmd_id integer PRIMARY KEY DEFAULT nextval('public.cmd_cmd_id_seq'::regclass)
cmd_module text NOT NULL
cmd_title text NOT NULL
cmd_descrip text
cmd_privname text
cmd_executable text NOT NULL
cmd_name text

Table te.pkgcmd Inherits cmd,

Tables referencing this one via Foreign Key Constraints:

Index - Schema te


Table: te.pkgcmdarg

te.pkgcmdarg Structure
F-Key Name Type Description
cmdarg_id integer PRIMARY KEY DEFAULT nextval('public.cmdarg_cmdarg_id_seq'::regclass)
te.pkgcmd.cmd_id cmdarg_cmd_id integer NOT NULL
cmdarg_order integer NOT NULL
cmdarg_arg text NOT NULL

Table te.pkgcmdarg Inherits cmdarg,

Index - Schema te


Table: te.pkgimage

te.pkgimage Structure
F-Key Name Type Description
image_id integer PRIMARY KEY DEFAULT nextval('public.image_image_id_seq'::regclass)
image_name text
image_descrip text
image_data text

Table te.pkgimage Inherits image,

Index - Schema te


Table: te.pkgmetasql

te.pkgmetasql Structure
F-Key Name Type Description
metasql_id integer PRIMARY KEY DEFAULT nextval('public.metasql_metasql_id_seq'::regclass)
metasql_group text
metasql_name text
metasql_notes text
metasql_query text
metasql_lastuser text
metasql_lastupdate date
metasql_grade integer NOT NULL

Table te.pkgmetasql Inherits metasql,

Index - Schema te


Table: te.pkgpriv

te.pkgpriv Structure
F-Key Name Type Description
priv_id integer PRIMARY KEY DEFAULT nextval('public.priv_priv_id_seq'::regclass)
priv_module text
priv_name text
priv_descrip text
priv_seq integer

Table te.pkgpriv Inherits priv,

Index - Schema te


Table: te.pkgreport

te.pkgreport Structure
F-Key Name Type Description
report_id integer PRIMARY KEY DEFAULT nextval('public.report_report_id_seq'::regclass)
report_name text
report_sys boolean
report_source text
report_descrip text
report_grade integer NOT NULL
report_loaddate timestamp without time zone

Table te.pkgreport Inherits report,

Index - Schema te


Table: te.pkgscript

te.pkgscript Structure
F-Key Name Type Description
script_id integer PRIMARY KEY DEFAULT nextval('public.script_script_id_seq'::regclass)
script_name text NOT NULL
script_order integer NOT NULL
script_enabled boolean NOT NULL DEFAULT false
script_source text NOT NULL
script_notes text

Table te.pkgscript Inherits script,

Index - Schema te


Table: te.pkguiform

te.pkguiform Structure
F-Key Name Type Description
uiform_id integer PRIMARY KEY DEFAULT nextval('public.uiform_uiform_id_seq'::regclass)
uiform_name text NOT NULL
uiform_order integer NOT NULL
uiform_enabled boolean NOT NULL DEFAULT false
uiform_source text NOT NULL
uiform_notes text

Table te.pkguiform Inherits uiform,

Index - Schema te


Table: te.tecustrate

Default Customer Billing rate for Time/Expense

te.tecustrate Structure
F-Key Name Type Description
public.custinfo.cust_id tecustrate_cust_id integer PRIMARY KEY
tecustrate_rate numeric(16,4) NOT NULL
tecustrate_id serial NOT NULL
public.curr_symbol.curr_id tecustrate_curr_id integer NOT NULL DEFAULT public.basecurrid()

Index - Schema te


Table: te.teemp

te.teemp Structure
F-Key Name Type Description
teemp_id serial NOT NULL
public.emp.emp_id teemp_emp_id integer
teemp_contractor boolean DEFAULT false

Index - Schema te


Table: te.teexp

Expense/Item

te.teexp Structure
F-Key Name Type Description
teexp_id integer PRIMARY KEY
teexp_expcat_id integer
teexp_accnt_id integer

Index - Schema te


Table: te.tehead

time/expense header

te.tehead Structure
F-Key Name Type Description
tehead_id serial PRIMARY KEY
tehead_number text DEFAULT nextval('timesheet_seq'::regclass)
tehead_weekending date
tehead_lastupdated timestamp without time zone NOT NULL DEFAULT now()
tehead_notes text
tehead_status character(1) NOT NULL DEFAULT 'O'::bpchar
tehead_emp_id integer
tehead_warehous_id integer NOT NULL
tehead_username text NOT NULL DEFAULT "current_user"()

 

te.tehead Constraints
Name Constraint
tehead_tehead_status_check CHECK ((tehead_status = ANY (ARRAY['O'::bpchar, 'A'::bpchar, 'C'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema te


Table: te.teitem

time/expense detail

te.teitem Structure
F-Key Name Type Description
teitem_id serial PRIMARY KEY
te.tehead.tehead_id teitem_tehead_id integer
teitem_linenumber integer NOT NULL
teitem_type character(1) NOT NULL

T or E
teitem_workdate date
teitem_cust_id integer
teitem_vend_id integer

future use - for payment of vendor for expenses
teitem_po text
teitem_item_id integer NOT NULL
teitem_qty numeric NOT NULL
teitem_rate numeric NOT NULL
teitem_total numeric NOT NULL
teitem_prjtask_id numeric
teitem_lastupdated timestamp without time zone NOT NULL DEFAULT ('now'::text)::timestamp(6) with time zone
teitem_billable boolean
teitem_prepaid boolean

Used for expenses only. CC paid expenses would be prepaid.
teitem_notes text
teitem_posted boolean DEFAULT false
public.curr_symbol.curr_id teitem_curr_id integer NOT NULL DEFAULT public.basecurrid()
teitem_uom_id integer
public.invcitem.invcitem_id teitem_invcitem_id integer
public.vodist.vodist_id teitem_vodist_id integer
teitem_postedvalue numeric NOT NULL
teitem_empcost numeric
teitem_teitem_tehead_id_idx teitem_tehead_id

Index - Schema te


Table: te.teprj

t/e information for projects

te.teprj Structure
F-Key Name Type Description
teprj_id serial PRIMARY KEY
teprj_prj_id integer
public.custinfo.cust_id teprj_cust_id integer
teprj_rate numeric
public.curr_symbol.curr_id teprj_curr_id integer

Index - Schema te


Table: te.teprjtask

t/e information for tasks

te.teprjtask Structure
F-Key Name Type Description
teprjtask_id serial PRIMARY KEY
teprjtask_cust_id integer
teprjtask_rate numeric
public.item.item_id teprjtask_item_id integer
public.prjtask.prjtask_id teprjtask_prjtask_id integer UNIQUE
public.curr_symbol.curr_id teprjtask_curr_id integer DEFAULT public.basecurrid()

Index - Schema te


Function: te.calcrate(numeric, bpchar)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pAmount ALIAS FOR $1;
pPeriod ALIAS FOR $2;
_state integer;
_count integer;

BEGIN
  -- Convert amount to hourly rate
  IF (pPeriod = 'H') THEN  -- hourly
    RETURN round(pAmount,2);
  ELSIF (pPeriod = 'D') THEN -- daily
    RETURN round(pAmount / 8, 2);
  ELSIF (pPeriod = 'W') THEN  -- weekly
    RETURN round(pAmount / 40, 2);
  ELSIF (pPeriod = 'BW') THEN  -- bi-weekly
    RETURN round(pAmount / 80, 2);
  ELSIF (pPeriod = 'M') THEN -- monthly
    RETURN round(pAmount / 160, 2);
  ELSIF (pPeriod = 'Y') THEN -- annually 
    RETURN round(pAmount / 2080, 2);
  ELSE
    RAISE EXCEPTION 'Unknown period type passed: %', pPeriod;
  END IF;

END;

Function: te.copyitem(integer, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSItemid ALIAS FOR $1;
  pTItemNumber ALIAS FOR $2;
  _itemid INTEGER;
  _r RECORD;
  _id INTEGER;

BEGIN
  _itemid := public.copyItem(pSItemid, pTItemNumber);

  INSERT INTO te.teexp
  SELECT _itemid, teexp_expcat_id, teexp_accnt_id
  FROM te.teexp src
  WHERE (src.teexp_id=pSItemid);

  RETURN _itemid;
END;

Function: te.invoicesheets(integer[])

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pHeadIDs ALIAS FOR $1;

_invcnum text;
_invcheadid integer;
_invcitemid integer;
_s record;
_t record;
_linenum integer;

BEGIN
       -- Loop through time sheet items with matching criteria and make invoices
       FOR _s in SELECT DISTINCT 
                   teitem_cust_id, 
                   teitem_po, 
                   prj_id, 
                   teitem_curr_id
       FROM te.tehead 
         JOIN te.teitem ON (teitem_tehead_id=tehead_id AND teitem_billable)
         JOIN prjtask ON (teitem_prjtask_id=prjtask_id)
         JOIN prj ON (prjtask_prj_id=prj_id)
       WHERE ((tehead_id IN (SELECT * FROM te.unnest(pHeadIDs) ) )
        AND (teitem_billable)
        AND (teitem_invcitem_id IS NULL))

       -- loop thru records and create invoices by customer, by PO for the provided headid
       LOOP
         --select nextval('invchead_invchead_id_seq') into _invcid;
         _invcnum := CAST(fetchInvcNumber() AS TEXT);
         _invcheadid := nextval('invchead_invchead_id_seq');
         _linenum := 1;

         INSERT INTO invchead
         SELECT _invcheadid, cust_id, -1, '', current_date, false, false, _invcnum,
           current_date, current_date, _s.teitem_po, '', '', cust_name, COALESCE(addr_line1,''),
           COALESCE(addr_line2,''), COALESCE(addr_line3,''), COALESCE(addr_city,''),
           COALESCE(addr_state,''), COALESCE(addr_postalcode,''), cntct_phone, 
           '', '', '', '', '', '', '', '', cust_salesrep_id, salesrep_commission, cust_terms_id,
           0, 0, '', -1, 0, '', '', COALESCE(addr_country,''), '', _s.prj_id, 
           _s.teitem_curr_id, current_date, false, null, null, null, null, null, cust_taxzone_id
         FROM custinfo
           JOIN salesrep ON (cust_salesrep_id=salesrep_id)
           LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
           LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
         WHERE (cust_id=_s.teitem_cust_id);

          -- loop thru all lines of the sheet
          FOR _t IN SELECT 
               teitem_id,
               teitem_linenumber, 
               tehead_warehous_id,
               teitem_type,
               tehead_emp_id,
               cust_taxzone_id,
               item_number,
               teitem_cust_id,
               teitem_po,
               teitem_item_id,
               teitem_qty,
               teitem_uom_id,
               teitem_rate,
               teitem_notes
             FROM te.teitem
               JOIN te.tehead ON (teitem_tehead_id = tehead_id)
               JOIN custinfo ON (cust_id = teitem_cust_id)
               JOIN item ON (item_id = teitem_item_id)
               JOIN prjtask ON (teitem_prjtask_id=prjtask_id)
               JOIN prj ON (prjtask_prj_id=prj_id)
             WHERE ((tehead_id IN (SELECT * FROM te.unnest(pHeadIDs) ) )
              AND (teitem_billable)
              AND (teitem_invcitem_id IS NULL)
              AND (item_id = teitem_item_id)
              AND (teitem_cust_id = _s.teitem_cust_id)
              AND (teitem_po = _s.teitem_po)
              AND (prj_id = _s.prj_id)
              AND (teitem_curr_id = _s.teitem_curr_id))
             ORDER BY teitem_linenumber
          LOOP
            _invcitemid := nextval('invcitem_invcitem_id_seq');

            INSERT INTO invcitem
            SELECT 
              _invcitemid, _invcheadid, _linenum, _t.teitem_item_id,
              _t.tehead_warehous_id, '', '', '', _t.teitem_qty, _t.teitem_qty, _t.teitem_rate,
              _t.teitem_rate, _t.teitem_notes, -1, getItemTaxType(item_id, _t.cust_taxzone_id), 
              _t.teitem_uom_id, itemuomtouomratio(item_id, _t.teitem_uom_id, item_inv_uom_id),
              _t.teitem_uom_id, itemuomtouomratio(item_id, _t.teitem_uom_id, item_inv_uom_id),
              null
            FROM item
            WHERE (item_id=_t.teitem_item_id);

            _linenum := _linenum + 1;
            
            -- Update the time sheet item record
            UPDATE te.teitem SET teitem_invcitem_id = _invcitemid WHERE (teitem_id = _t.teitem_id);
            
          END LOOP;
       END LOOP;

RETURN 1;
END;

Function: te.postsheet(integer, text, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
pTeheadId ALIAS FOR $1;
pPhrase1 ALIAS FOR $2;
pPhrase2 ALIAS FOR $3; 
_r record;
_notes TEXT;
_value NUMERIC;
_olaccntid INTEGER;
_expaccntid INTEGER;
_count INTEGER;

BEGIN
  -- Validate: No posting for contractors
  IF (SELECT (count(teemp_id) > 0) 
      FROM te.tehead
        JOIN te.teemp ON (tehead_emp_id=teemp_emp_id)
      WHERE ((tehead_id=pTeheadId)
        AND (teemp_contractor))) THEN
    RAISE EXCEPTION 'Time and Expense Sheets can not be posted for contractors.  Voucher instead.';
  END IF;
  
  -- Get labor and overhead account
  SELECT accnt_id INTO _olaccntid
  FROM accnt
  WHERE (accnt_id=fetchmetricvalue('PrjLaborAndOverhead'));

  GET DIAGNOSTICS _count = ROW_COUNT;
  IF (_count = 0) THEN
    RAISE EXCEPTION 'No valid Project Labor and Overhead Account Defined';
  END IF;

  -- Get applicable time sheets
  FOR _r IN 
    SELECT tehead_number,
      teitem_id, teitem_linenumber, teitem_type, teitem_notes,
      item_descrip1, teitem_qty,
      teexp_expcat_id, teexp_accnt_id, 
      emp_code, emp_wage, emp_wage_period,
      prj_id, prj_number
    FROM te.tehead
     JOIN te.teitem ON (teitem_tehead_id=tehead_id)
     JOIN item ON (teitem_item_id=item_id)
     JOIN te.teexp ON (teitem_item_id=teexp_id)
     JOIN emp ON (tehead_emp_id=emp_id)
     JOIN prjtask ON (prjtask_id=teitem_prjtask_id)
     JOIN prj ON (prj_id=prjtask_prj_id)
    WHERE ((tehead_id = pTeheadId)
     AND (NOT teitem_posted)
     AND (teitem_vodist_id IS NULL)
     AND (teitem_type = 'T'))

  LOOP  
    -- Determine value
    _value := te.calcRate(_r.emp_wage, _r.emp_wage_period) * _r.teitem_qty;

    -- Determine G/L account to post to
    IF (_r.teexp_accnt_id > 1) THEN
      _expaccntid := getPrjAccntId(_r.prj_id, _r.teexp_accnt_id);
    ELSE
      SELECT getPrjAccntId(_r.prj_id, expcat_exp_accnt_id) INTO _expaccntid
      FROM expcat
      WHERE (expcat_id=_r.teexp_expcat_id);
    END IF;

    -- Execute the posting
    _notes := (pPhrase1 || _r.item_descrip1 || '/' || _r.emp_code || pPhrase2 || ' ' || _r.prj_number);
    PERFORM insertGLTransaction( 'T/E', 'TE', _r.tehead_number, _notes,
                                 _olaccntid, _expaccntid, -1,
                                 _value, current_date );

    -- Update the time sheet item
    UPDATE te.teitem SET 
      teitem_posted = true,
      teitem_postedvalue = teitem_postedvalue + _value
    WHERE (teitem_id=_r.teitem_id);
                        
  END LOOP;
          
RETURN 1;
END;

Function: te.sheetstate(integer, bpchar)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTeheadId ALIAS FOR $1;
  pType     ALIAS FOR $2;
  _state    INTEGER := -1;

BEGIN
  -- Check and return the process state of the sheet
  --    1 = All processed
  --    0 = Processing required
  --   -1 = Not Applicable

  IF (pType = 'I') THEN
    SELECT MIN(CASE teitem_invcitem_id IS NULL WHEN TRUE THEN 0 ELSE 1 END) INTO _state
      FROM te.teitem
     WHERE ((teitem_tehead_id=pTeheadId)
        AND (teitem_billable)
        AND (teitem_qty >= 0));

  ELSIF (pType = 'V') THEN
    -- todo: why outer join then check teitem_type and vend_id is not null?
    SELECT MIN(CASE teitem_vodist_id IS NULL WHEN TRUE THEN 0 ELSE 1 END) INTO _state
      FROM te.tehead
        JOIN emp ON (tehead_emp_id=emp_id)
        LEFT OUTER JOIN te.teemp ON (emp_id=teemp_emp_id)
        LEFT OUTER JOIN te.teitem ON (teitem_tehead_id=tehead_id)
        LEFT OUTER JOIN vendinfo ON (UPPER(emp_number)=UPPER(vend_number))
      WHERE ((teitem_tehead_id=pTeheadId)
         AND ((teitem_type = 'E' AND NOT teitem_prepaid) 
           OR (teitem_type = 'T' AND COALESCE(teemp_contractor,false)))
         AND (vend_id IS NOT NULL)
         AND (teitem_qty > 0));

  ELSIF (pType = 'P') THEN
    SELECT MIN(CASE teitem_posted WHEN FALSE THEN 0 ELSE 1 END) INTO _state
      FROM te.teitem
      JOIN te.tehead ON (teitem_tehead_id=tehead_id)
      JOIN te.teemp ON (tehead_emp_id=teemp_emp_id)
     WHERE ((teitem_tehead_id=pTeheadId)
        AND (teitem_type = 'T')
        AND (NOT teemp_contractor));

  ELSE
    -- TODO: either make ErrorReporter::error find this or use xtuple
    RAISE EXCEPTION 'Unknown process type % [xtte: sheetstate, -2, %]',
                    pType, pType;
  END IF;

  RETURN _state;

END;

Function: te.triggertehead()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
_r RECORD;
_sense INTEGER := 0;

BEGIN

  -- Determine whether we are adding or subtracting totals
  IF (TG_OP = 'UPDATE') THEN
    IF (OLD.tehead_status = 'O' AND NEW.tehead_status = 'A') THEN
    -- Approving so add
      _sense := 1;
    ELSIF  (OLD.tehead_status = 'A' AND NEW.tehead_status = 'O') THEN
    -- Unapproving so subtract
      _sense := -1;
    END IF;
  END IF;

  IF (_sense != 0) THEN
    -- Loop thru all lines of the sheet and update project
    FOR _r in 
      SELECT teitem_prjtask_id, teitem_type, teitem_qty, teitem_total 
      FROM te.teitem
      WHERE teitem_tehead_id = NEW.tehead_id

    LOOP
      IF (_r.teitem_type = 'T') THEN
        UPDATE prjtask SET 
          prjtask_hours_actual = prjtask_hours_actual + _r.teitem_qty * _sense
        WHERE prjtask_id = _r.teitem_prjtask_id;
      ELSE
        UPDATE prjtask SET 
          prjtask_exp_actual = prjtask_exp_actual + _r.teitem_total * _sense
        WHERE prjtask_id = _r.teitem_prjtask_id;
      END IF;
            
    END LOOP;
  END IF;

  RETURN NEW;
END;

Function: te.triggerteitem()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
_r RECORD;
_status CHAR(1) := 'O';

BEGIN
  -- Validate whether we can take this action
  IF (TG_OP = 'UPDATE') THEN
    IF ((OLD.teitem_type != NEW.teitem_type)
      OR (OLD.teitem_workdate != NEW.teitem_workdate)
      OR (OLD.teitem_cust_id != NEW.teitem_cust_id)
      OR (OLD.teitem_po != NEW.teitem_po)
      OR (OLD.teitem_item_id != NEW.teitem_item_id)
      OR (OLD.teitem_qty != NEW.teitem_qty)
      OR (OLD.teitem_rate != NEW.teitem_rate)
      OR (OLD.teitem_total != NEW.teitem_total)
      OR (OLD.teitem_billable != NEW.teitem_billable)
      OR (OLD.teitem_prepaid != NEW.teitem_prepaid)
      OR (OLD.teitem_notes != NEW.teitem_notes)) THEN
      
      SELECT tehead_status INTO _status FROM te.tehead WHERE tehead_id=NEW.teitem_tehead_id;
    END IF;
  ELSIF (TG_OP = 'INSERT') THEN
    SELECT tehead_status INTO _status FROM te.tehead WHERE tehead_id=NEW.teitem_tehead_id;
  ELSE -- Must be delete
    SELECT tehead_status INTO _status FROM te.tehead WHERE tehead_id=OLD.teitem_tehead_id;
  END IF;

  IF (_status != 'O') THEN
    RAISE EXCEPTION 'Time and Expense Sheets may only be edited or deleted when the status is Open';
  END IF;

  _status := 'C';
  
  -- Update header status, default is to close if all processing complete
  IF (TG_OP = 'UPDATE') THEN
    IF ((COALESCE(OLD.teitem_invcitem_id,-1) != COALESCE(NEW.teitem_invcitem_id,-1))
      OR (COALESCE(OLD.teitem_vodist_id,-1) != COALESCE(NEW.teitem_vodist_id,-1))
      OR (OLD.teitem_posted != NEW.teitem_posted)) THEN

      SELECT 
        te.sheetstate(NEW.teitem_tehead_id, 'I') AS invoiced,
        te.sheetstate(NEW.teitem_tehead_id, 'V') AS vouchered,
        te.sheetstate(NEW.teitem_tehead_id, 'P') AS posted
      INTO _r;

      IF (_r.invoiced = 0 OR _r.vouchered = 0 OR _r.posted = 0) THEN
        _status := 'A'; -- Something is still open, so approved
      END IF;
    
      UPDATE te.tehead SET tehead_status = _status WHERE (tehead_id=NEW.teitem_tehead_id);
    END IF;
  END IF;

  -- Update header with last use info
  IF (TG_OP = 'DELETE') THEN
    UPDATE te.tehead SET
      tehead_lastupdated=('now'::text)::timestamp(6) with time zone
    WHERE (tehead_id=OLD.teitem_tehead_id);
  ELSE
    UPDATE te.tehead SET
      tehead_lastupdated=('now'::text)::timestamp(6) with time zone,
      tehead_username=current_user
    WHERE (tehead_id=NEW.teitem_tehead_id);
  END IF;

  RETURN NEW;
END;

Function: te.triggerteprj()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _update BOOLEAN := false;
BEGIN

  IF (TG_OP = 'INSERT') THEN
    _update = true;
  ELSIF (TG_OP = 'UPDATE') THEN
    IF (COALESCE(OLD.teprj_cust_id,-1) != COALESCE(NEW.teprj_cust_id,-1)) THEN
      _update = true;
    END IF;
  END IF;

  IF (_update) THEN
      UPDATE te.teprjtask SET teprjtask_cust_id=NEW.teprj_cust_id
      FROM prjtask
      WHERE ((teprjtask_prjtask_id=prjtask_id)
      AND (prjtask_prj_id=NEW.teprj_prj_id));
  END IF;
  
  RETURN NEW;
END;

Function: te.unnest(anyarray)

Returns: SET OF anyelement

Language: SQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
SELECT $1[i] FROM
    generate_series(array_lower($1,1),
                    array_upper($1,1)) i;

Function: te.vouchersheet(integer)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pHeadID ALIAS FOR $1;
  _distamt  NUMERIC;
  _glaccnt  INTEGER;
  _notes    TEXT;
  _s        RECORD;
  _total    NUMERIC := 0;
  _v        RECORD;
  _vodistid INTEGER;
  _voheadid INTEGER;

BEGIN
  FOR _v IN
    -- distinct filters duplicate rows returned because of the teitem join
    -- TODO: can we push the teitem down into the loop and avoid the distinct?
    SELECT DISTINCT
           tehead_id, tehead_number,   tehead_weekending,          tehead_notes,
           teitem_curr_id,
           emp_wage, emp_wage_period,
           vend_id,   vend_taxzone_id, vend_terms_id, vend_number, vend_1099,
           COALESCE(teemp_contractor, false) AS isContractor
      FROM te.tehead
      JOIN te.teitem ON (teitem_tehead_id=tehead_id)
      JOIN emp       ON (tehead_emp_id=emp_id)
      JOIN vendinfo  ON (UPPER(emp_number)=UPPER(vend_number))
      LEFT OUTER JOIN te.teemp ON (emp_id=teemp_emp_id)
    WHERE ((tehead_id      = pHeadID)
       AND (teitem_prepaid = false)
       AND (teitem_vodist_id IS NULL)
       AND (teitem_type = 'E' OR (COALESCE(teemp_contractor,false) AND (teitem_empcost > 0 OR emp_wage > 0 ))))  LOOP

     INSERT INTO vohead (vohead_id,        vohead_number,     vohead_vend_id,
                         vohead_distdate,  vohead_docdate,
                         vohead_duedate,
                         vohead_terms_id,  vohead_taxzone_id, vohead_invcnumber,
                         vohead_reference, vohead_amount,     vohead_1099,
                         vohead_curr_id,   vohead_notes,      vohead_posted,
                         vohead_misc,      vohead_pohead_id)
                 VALUES (DEFAULT,              fetchVoNumber(),    _v.vend_id,
                         _v.tehead_weekending, _v.tehead_weekending,
                         determineDueDate(_v.vend_terms_id, _v.tehead_weekending),
                         _v.vend_terms_id,     _v.vend_taxzone_id, 'N/A',
                         ('T&E Sheet ' || _v.tehead_number),    0, _v.vend_1099,
                         _v.teitem_curr_id,    _v.tehead_notes, false,
                         true,                 -1)
     RETURNING vohead_id INTO _voheadid;

     FOR _s IN
       SELECT teitem_id,       teitem_linenumber, teitem_workdate, teitem_type,
              item_number,     teitem_item_id,    teitem_qty,      prjtask_prj_id,
              CASE
                WHEN teitem_empcost > 0 THEN teitem_empcost
                ELSE te.calcRate(_v.emp_wage, _v.emp_wage_period)
              END AS rate,
              teitem_total,    teitem_type,
              teexp_expcat_id, teexp_accnt_id
         FROM te.teitem
         JOIN te.teexp ON (teitem_item_id=teexp_id)
         JOIN item     ON (teitem_item_id=item_id)
         JOIN prjtask  ON (teitem_prjtask_id=prjtask_id)
        WHERE ((teitem_tehead_id = _v.tehead_id)
           AND (teitem_curr_id   = _v.teitem_curr_id)
           AND (teitem_prepaid   = false)
           AND (teitem_vodist_id IS NULL)
           AND (teitem_type = 'E' OR (_v.isContractor AND (teitem_empcost > 0 OR _v.emp_wage > 0 )))) 


       -- Loop thru records and create vouchers by supplier for the provided headid
     LOOP
        -- insert vodist records here
        _vodistid = nextval('vodist_vodist_id_seq');

        -- Map expense directly to account so we can get project account mapping if applicable
        IF (_s.teexp_accnt_id > 1) THEN
          _glaccnt := getPrjAccntId(_s.prjtask_prj_id, _s.teexp_accnt_id);
        ELSE
          SELECT getPrjAccntId(_s.prjtask_prj_id, expcat_exp_accnt_id) INTO _glaccnt
            FROM expcat
           WHERE (expcat_id=_s.teexp_expcat_id);
        END IF;

        IF (_s.teitem_type = 'T') THEN -- Time sheet record
          _notes := formatdate(_s.teitem_workdate) || E'\t' || _s.item_number ||
                    E'\t' || formatQty(_s.teitem_qty) || ' hours' || E'\t';
          _distamt := _s.rate * _s.teitem_qty;
        ELSE -- Expense record
          _notes := formatdate(_s.teitem_workdate) || E'\t' || _s.item_number ||
                    E'\t' || E'\t';
          _distamt := _s.teitem_total;
        END IF;

        INSERT INTO vodist (vodist_id,          vodist_vohead_id, vodist_poitem_id,
                            vodist_costelem_id, vodist_accnt_id,  vodist_amount,
                            vodist_expcat_id,   vodist_notes)
                    VALUES (_vodistid, _voheadid, -1,
                            -1,        _glaccnt,  _distamt,
                            -1,        _notes);
        _total := _total + _distamt;

        -- Update the te.teitem record with the relationship
        UPDATE te.teitem SET teitem_vodist_id = _vodistid WHERE teitem_id = _s.teitem_id;
     END LOOP;

    UPDATE vohead SET vohead_amount = _total WHERE (vohead_id=_voheadid);
     _total := 0;

  END LOOP;

  RETURN 1;
END;

Schema xtdesktop

Schema to hold contents of xtdesktop


Table: xtdesktop.pkgcmd

xtdesktop.pkgcmd Structure
F-Key Name Type Description
cmd_id integer PRIMARY KEY DEFAULT nextval('public.cmd_cmd_id_seq'::regclass)
cmd_module text NOT NULL
cmd_title text NOT NULL
cmd_descrip text
cmd_privname text
cmd_executable text NOT NULL
cmd_name text

Table xtdesktop.pkgcmd Inherits cmd,

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtdesktop


Table: xtdesktop.pkgcmdarg

xtdesktop.pkgcmdarg Structure
F-Key Name Type Description
cmdarg_id integer PRIMARY KEY DEFAULT nextval('public.cmdarg_cmdarg_id_seq'::regclass)
xtdesktop.pkgcmd.cmd_id cmdarg_cmd_id integer NOT NULL
cmdarg_order integer NOT NULL
cmdarg_arg text NOT NULL

Table xtdesktop.pkgcmdarg Inherits cmdarg,

Index - Schema xtdesktop


Table: xtdesktop.pkgimage

xtdesktop.pkgimage Structure
F-Key Name Type Description
image_id integer PRIMARY KEY DEFAULT nextval('public.image_image_id_seq'::regclass)
image_name text
image_descrip text
image_data text

Table xtdesktop.pkgimage Inherits image,

Index - Schema xtdesktop


Table: xtdesktop.pkgmetasql

xtdesktop.pkgmetasql Structure
F-Key Name Type Description
metasql_id integer PRIMARY KEY DEFAULT nextval('public.metasql_metasql_id_seq'::regclass)
metasql_group text
metasql_name text
metasql_notes text
metasql_query text
metasql_lastuser text
metasql_lastupdate date
metasql_grade integer NOT NULL

Table xtdesktop.pkgmetasql Inherits metasql,

Index - Schema xtdesktop


Table: xtdesktop.pkgpriv

xtdesktop.pkgpriv Structure
F-Key Name Type Description
priv_id integer PRIMARY KEY DEFAULT nextval('public.priv_priv_id_seq'::regclass)
priv_module text
priv_name text
priv_descrip text
priv_seq integer

Table xtdesktop.pkgpriv Inherits priv,

Index - Schema xtdesktop


Table: xtdesktop.pkgreport

xtdesktop.pkgreport Structure
F-Key Name Type Description
report_id integer PRIMARY KEY DEFAULT nextval('public.report_report_id_seq'::regclass)
report_name text
report_sys boolean
report_source text
report_descrip text
report_grade integer NOT NULL
report_loaddate timestamp without time zone

Table xtdesktop.pkgreport Inherits report,

Index - Schema xtdesktop


Table: xtdesktop.pkgscript

xtdesktop.pkgscript Structure
F-Key Name Type Description
script_id integer PRIMARY KEY DEFAULT nextval('public.script_script_id_seq'::regclass)
script_name text NOT NULL
script_order integer NOT NULL
script_enabled boolean NOT NULL DEFAULT false
script_source text NOT NULL
script_notes text

Table xtdesktop.pkgscript Inherits script,

Index - Schema xtdesktop


Table: xtdesktop.pkguiform

xtdesktop.pkguiform Structure
F-Key Name Type Description
uiform_id integer PRIMARY KEY DEFAULT nextval('public.uiform_uiform_id_seq'::regclass)
uiform_name text NOT NULL
uiform_order integer NOT NULL
uiform_enabled boolean NOT NULL DEFAULT false
uiform_source text NOT NULL
uiform_notes text

Table xtdesktop.pkguiform Inherits uiform,

Index - Schema xtdesktop


Function: xtdesktop.fetchwelcomehtml()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _html TEXT;

BEGIN

  _html := '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8"> 
	<TITLE></TITLE> 
	<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0  (Unix)"> 
	<META NAME="CREATED" CONTENT="20100422;16091500"> 
	<META NAME="CHANGED" CONTENT="20100422;16095800"> 
	<META NAME="Info 1" CONTENT=""> 
	<META NAME="Info 2" CONTENT=""> 
	<META NAME="Info 3" CONTENT=""> 
	<META NAME="Info 4" CONTENT=""> 
	<STYLE TYPE="text/css"> 
	<!--
		@page { margin: 0.79in }
		P { margin-bottom: 0.08in }
	--> 
	</STYLE> 
</HEAD> 
<BODY LANG="en-US" DIR="LTR"> 
<P STYLE="margin-bottom: 0in"><B>Welcome to xTuple</B></P> 
<P STYLE="margin-bottom: 0in"><BR> 
</P> 
<P STYLE="margin-bottom: 0in">You are not connected to the internet
at this time</P> 
</BODY> 
</HTML>';

  RETURN _html;

END;

Schema xtpos

This file is part of the xtpos Package for xTuple ERP, and is Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. It is licensed to you under the xTuple End-User License Agreement ("the EULA"), the full text of which is available at www.xtuple.com/EULA. While the EULA gives you access to source code and encourages your involvement in the development process, this Package is not free software. By using this software, you agree to be bound by the terms of the EULA.


View: xtpos.api_cashregister

Cash Register

xtpos.api_cashregister Structure
F-Key Name Type Description
site text
terminal text
active boolean
opened text
opening_balance numeric
current_balance numeric
total_sales numeric
cash_sales numeric
credit_card_sales numeric
check_sales numeric
SELECT site.warehous_code AS site
, terminal.terminal_number AS terminal
, CASE WHEN 
(reghist.reghist_id IS NULL) THEN false ELSE true END AS active
, formatdatetime
(reghist.reghist_open_time) AS opened
, COALESCE
(opn.regdetail_endbal
     , (0)::numeric
) AS opening_balance
, COALESCE
(CASE WHEN 
     (reghist.reghist_id IS NULL) THEN 
     (
      SELECT regdetail.regdetail_endbal 
        FROM (xtpos.regdetail 
              JOIN xtpos.reghist 
                ON (
                       (reghist.reghist_id = regdetail.regdetail_reghist_id)
                 )
           )
       WHERE (reghist.reghist_terminal_id = rtlsiteterm.rtlsiteterm_terminal_id)
    ORDER BY regdetail.regdetail_time DESC LIMIT 1
     ) ELSE 
     (
           (COALESCE
                 (opn.regdetail_endbal
                       , (0)::numeric
                 ) + COALESCE
                 (sum
                       (
                             (adj.regdetail_transferamt + adj.regdetail_adjustamt)
                       )
                       , (0)::numeric
                 )
           ) + xtpos.reghistsales
           (reghist.reghist_id
                 ,'S'::text
           )
     ) END
     , (0)::numeric
) AS current_balance
, xtpos.reghistsales
(reghist.reghist_id) AS total_sales
, xtpos.reghistsales
(reghist.reghist_id
     ,'S'::text
) AS cash_sales
, xtpos.reghistsales
(reghist.reghist_id
     ,'C'::text
) AS credit_card_sales
, xtpos.reghistsales
(reghist.reghist_id
     ,'K'::text
) AS check_sales 
FROM (
     (
           (
                 (
                       (
                             (xtpos.rtlsiteterm 
                                JOIN xtpos.rtlsite 
                                  ON (
                                         (rtlsite.rtlsite_id = rtlsiteterm.rtlsiteterm_rtlsite_id)
                                   )
                             )
                          JOIN xtpos.terminal 
                            ON (
                                   (terminal.terminal_id = rtlsiteterm.rtlsiteterm_terminal_id)
                             )
                       )
                    JOIN site
                       () site
                       (warehous_id
                             , warehous_code
                             , warehous_descrip
                             , warehous_fob
                             , warehous_active
                             , warehous_counttag_prefix
                             , warehous_counttag_number
                             , warehous_bol_prefix
                             , warehous_bol_number
                             , warehous_shipping
                             , warehous_useslips
                             , warehous_usezones
                             , warehous_aislesize
                             , warehous_aislealpha
                             , warehous_racksize
                             , warehous_rackalpha
                             , warehous_binsize
                             , warehous_binalpha
                             , warehous_locationsize
                             , warehous_locationalpha
                             , warehous_enforcearbl
                             , warehous_default_accnt_id
                             , warehous_shipping_commission
                             , warehous_cntct_id
                             , warehous_addr_id
                             , warehous_transit
                             , warehous_shipform_id
                             , warehous_shipvia_id
                             , warehous_shipcomments
                             , warehous_costcat_id
                             , warehous_sitetype_id
                             , warehous_taxzone_id
                             , warehous_sequence
                       )
                      ON (
                             (site.warehous_id = rtlsite.rtlsite_warehous_id)
                       )
                 )
         LEFT JOIN xtpos.reghist 
                ON (
                       (
                             (reghist.reghist_terminal_id = terminal.terminal_id)
                           AND reghist.reghist_open
                       )
                 )
           )
   LEFT JOIN xtpos.regdetail opn 
          ON (
                 (
                       (opn.regdetail_reghist_id = reghist.reghist_id)
                     AND (opn.regdetail_type = 'O'::bpchar)
                 )
           )
     )
LEFT JOIN xtpos.regdetail adj 
    ON (
           (
                 (adj.regdetail_reghist_id = reghist.reghist_id)
               AND (adj.regdetail_type = 'A'::bpchar)
           )
     )
)
WHERE site.warehous_active 
GROUP BY site.warehous_code
, terminal.terminal_number
, reghist.reghist_id
, reghist.reghist_open_time
, opn.regdetail_startbal
, opn.regdetail_endbal
, rtlsiteterm.rtlsiteterm_terminal_id 
ORDER BY site.warehous_code
, terminal.terminal_number;

Index - Schema xtpos


View: xtpos.api_retailsite

Retail Site

xtpos.api_retailsite Structure
F-Key Name Type Description
site text
tax_zone text
quote_days integer
asset text
adjustment text
check_clearing text
SELECT whsinfo.warehous_code AS site
, taxzone.taxzone_code AS tax_zone
, rtlsite.rtlsite_quotedays AS quote_days
, formatglaccount
(rtlsite.rtlsite_asset_accnt_id) AS asset
, formatglaccount
(rtlsite.rtlsite_adjust_accnt_id) AS adjustment
, formatglaccount
(rtlsite.rtlsite_chkclr_accnt_id) AS check_clearing 
FROM (
     (xtpos.rtlsite 
        JOIN whsinfo 
          ON (
                 (rtlsite.rtlsite_warehous_id = whsinfo.warehous_id)
           )
     )
LEFT JOIN taxzone 
    ON (
           (rtlsite.rtlsite_taxzone_id = taxzone.taxzone_id)
     )
)
ORDER BY whsinfo.warehous_code;

Index - Schema xtpos


View: xtpos.api_retailsitebankaccnt

Retail Site Bank Account

xtpos.api_retailsitebankaccnt Structure
F-Key Name Type Description
site text
bank_account text
SELECT whsinfo.warehous_code AS site
, bankaccnt.bankaccnt_name AS bank_account 
FROM xtpos.rtlsitebnkacct
, xtpos.rtlsite
, bankaccnt
, whsinfo 
WHERE (
     (
           (rtlsite.rtlsite_id = rtlsitebnkacct.rtlsitebnkacct_rtlsite_id)
         AND (rtlsitebnkacct.rtlsitebnkacct_bankaccnt_id = bankaccnt.bankaccnt_id)
     )
   AND (rtlsite.rtlsite_warehous_id = whsinfo.warehous_id)
);

Index - Schema xtpos


View: xtpos.api_retailsiteterminal

Retail Site Terminal

xtpos.api_retailsiteterminal Structure
F-Key Name Type Description
site text
terminal text
SELECT whsinfo.warehous_code AS site
, terminal.terminal_number AS terminal 
FROM (
     (
           (xtpos.rtlsite 
              JOIN xtpos.rtlsiteterm 
                ON (
                       (rtlsite.rtlsite_id = rtlsiteterm.rtlsiteterm_rtlsite_id)
                 )
           )
        JOIN xtpos.terminal 
          ON (
                 (rtlsiteterm.rtlsiteterm_terminal_id = terminal.terminal_id)
           )
     )
  JOIN whsinfo 
    ON (
           (rtlsite.rtlsite_warehous_id = whsinfo.warehous_id)
     )
);

Index - Schema xtpos


View: xtpos.api_sale

Sale

xtpos.api_sale Structure
F-Key Name Type Description
sale_number text
type text
closed boolean
customer_number text
contact_number text
honorific text
first text
middle text
last text
suffix text
job_title text
voice text
alternate text
fax text
email text
web text
contact_change text
address_number text
address1 text
address2 text
address3 text
city text
state text
postalcode text
country text
address_change text
date timestamp with time zone
sales_rep text
notes text
site text
terminal text
tax_zone text
subtotal numeric
tax numeric
total numeric
SELECT salehead.salehead_number AS sale_number
, CASE WHEN 
(salehead.salehead_type = 'S'::bpchar) THEN 'Sale'::text WHEN 
(salehead.salehead_type = 'Q'::bpchar) THEN 'Quote'::text WHEN 
(salehead.salehead_type = 'R'::bpchar) THEN 'Return'::text ELSE 'Error'::text END AS type
, CASE WHEN 
(salehead.salehead_closed 
    OR (salehead.salehead_type = ANY 
           (ARRAY['S'::bpchar
                 ,'R'::bpchar]
           )
     )
) THEN salehead.salehead_closed ELSE xtpos.checkstatus
(salehead.salehead_id) END AS closed
, custinfo.cust_number AS customer_number
, c.cntct_number AS contact_number
, c.cntct_honorific AS honorific
, c.cntct_first_name AS first
, c.cntct_middle AS middle
, c.cntct_last_name AS last
, c.cntct_suffix AS suffix
, c.cntct_title AS job_title
, c.cntct_phone AS voice
, c.cntct_phone2 AS alternate
, c.cntct_fax AS fax
, c.cntct_email AS email
, c.cntct_webaddr AS web
,''::text AS contact_change
, a.addr_number AS address_number
, a.addr_line1 AS address1
, a.addr_line2 AS address2
, a.addr_line3 AS address3
, a.addr_city AS city
, a.addr_state AS state
, a.addr_postalcode AS postalcode
, a.addr_country AS country
,''::text AS address_change
, salehead.salehead_time AS date
, salesrep.salesrep_number AS sales_rep
, salehead.salehead_notes AS notes
, site.warehous_code AS site
, terminal.terminal_number AS terminal
, taxzone.taxzone_code AS tax_zone
, COALESCE
(sum
     (round
           (
                 (abs
                       (saleitem.saleitem_qty) * saleitem.saleitem_unitprice
                 )
                 , 2
           )
     )
     , (0)::numeric
) AS subtotal
, xtpos.saletax
(salehead.salehead_id) AS tax
, COALESCE
(
     (sum
           (round
                 (
                       (abs
                             (saleitem.saleitem_qty) * saleitem.saleitem_unitprice
                       )
                       , 2
                 )
           ) + abs
           (xtpos.saletax
                 (salehead.salehead_id)
           )
     )
     , (0)::numeric
) AS total 
FROM (
     (
           (
                 (
                       (
                             (
                                   (
                                         (xtpos.salehead 
                                            JOIN site
                                               () site
                                               (warehous_id
                                                     , warehous_code
                                                     , warehous_descrip
                                                     , warehous_fob
                                                     , warehous_active
                                                     , warehous_counttag_prefix
                                                     , warehous_counttag_number
                                                     , warehous_bol_prefix
                                                     , warehous_bol_number
                                                     , warehous_shipping
                                                     , warehous_useslips
                                                     , warehous_usezones
                                                     , warehous_aislesize
                                                     , warehous_aislealpha
                                                     , warehous_racksize
                                                     , warehous_rackalpha
                                                     , warehous_binsize
                                                     , warehous_binalpha
                                                     , warehous_locationsize
                                                     , warehous_locationalpha
                                                     , warehous_enforcearbl
                                                     , warehous_default_accnt_id
                                                     , warehous_shipping_commission
                                                     , warehous_cntct_id
                                                     , warehous_addr_id
                                                     , warehous_transit
                                                     , warehous_shipform_id
                                                     , warehous_shipvia_id
                                                     , warehous_shipcomments
                                                     , warehous_costcat_id
                                                     , warehous_sitetype_id
                                                     , warehous_taxzone_id
                                                     , warehous_sequence
                                               )
                                              ON (
                                                     (salehead.salehead_warehous_id = site.warehous_id)
                                               )
                                         )
                                      JOIN xtpos.terminal 
                                        ON (
                                               (salehead.salehead_terminal_id = terminal.terminal_id)
                                         )
                                   )
                           LEFT JOIN custinfo 
                                  ON (
                                         (salehead.salehead_cust_id = custinfo.cust_id)
                                   )
                             )
                     LEFT JOIN cntct c 
                            ON (
                                   (custinfo.cust_cntct_id = c.cntct_id)
                             )
                       )
               LEFT JOIN addr a 
                      ON (
                             (c.cntct_addr_id = a.addr_id)
                       )
                 )
         LEFT JOIN salesrep 
                ON (
                       (salehead.salehead_salesrep_id = salesrep.salesrep_id)
                 )
           )
   LEFT JOIN xtpos.saleitem 
          ON (
                 (salehead.salehead_id = saleitem.saleitem_salehead_id)
           )
     )
LEFT JOIN taxzone 
    ON (
           (salehead.salehead_taxzone_id = taxzone.taxzone_id)
     )
)
GROUP BY salehead.salehead_id
, salehead.salehead_number
, salehead.salehead_type
, salehead.salehead_closed
, custinfo.cust_number
, c.cntct_number
, c.cntct_honorific
, c.cntct_first_name
, c.cntct_middle
, c.cntct_last_name
, c.cntct_suffix
, c.cntct_title
, c.cntct_phone
, c.cntct_phone2
, c.cntct_fax
, c.cntct_email
, c.cntct_webaddr
, a.addr_number
, a.addr_line1
, a.addr_line2
, a.addr_line3
, a.addr_city
, a.addr_state
, a.addr_postalcode
, a.addr_country
, salehead.salehead_time
, site.warehous_code
, salesrep.salesrep_number
, terminal.terminal_number
, salehead.salehead_notes
, taxzone.taxzone_code 
ORDER BY salehead.salehead_number;

Index - Schema xtpos


View: xtpos.api_saleitem

Sale Item

xtpos.api_saleitem Structure
F-Key Name Type Description
sale_number text
line_number integer
item_number text
upc text
description text
qty numeric
price numeric
extension numeric
tax numeric
SELECT salehead.salehead_number AS sale_number
, saleitem.saleitem_linenumber AS line_number
, item.item_number
, item.item_upccode AS upc
, item.item_descrip1 AS description
, abs
(saleitem.saleitem_qty) AS qty
, round
(saleitem.saleitem_unitprice
     , 2
) AS price
, round
(
     (abs
           (saleitem.saleitem_qty) * saleitem.saleitem_unitprice
     )
     , 2
) AS extension
, abs
(round
     (COALESCE
           (sum
                 (saleitemtax.taxhist_tax)
                 , (0)::numeric
           )
           , 2
     )
) AS tax 
FROM (
     (
           (
                 (xtpos.saleitem 
                    JOIN xtpos.salehead 
                      ON (
                             (salehead.salehead_id = saleitem.saleitem_salehead_id)
                       )
                 )
              JOIN itemsite 
                ON (
                       (itemsite.itemsite_id = saleitem.saleitem_itemsite_id)
                 )
           )
        JOIN item 
          ON (
                 (item.item_id = itemsite.itemsite_item_id)
           )
     )
LEFT JOIN xtpos.saleitemtax 
    ON (
           (saleitem.saleitem_id = saleitemtax.taxhist_parent_id)
     )
)
GROUP BY salehead.salehead_number
, saleitem.saleitem_linenumber
, item.item_number
, item.item_upccode
, item.item_descrip1
, saleitem.saleitem_qty
, saleitem.saleitem_unitprice 
ORDER BY salehead.salehead_number
, saleitem.saleitem_linenumber;

Index - Schema xtpos


Table: xtpos.pkgcmd

xtpos.pkgcmd Structure
F-Key Name Type Description
cmd_id integer PRIMARY KEY DEFAULT nextval('public.cmd_cmd_id_seq'::regclass)
cmd_module text NOT NULL
cmd_title text NOT NULL
cmd_descrip text
cmd_privname text
cmd_executable text NOT NULL
cmd_name text

Table xtpos.pkgcmd Inherits cmd,

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.pkgcmdarg

xtpos.pkgcmdarg Structure
F-Key Name Type Description
cmdarg_id integer PRIMARY KEY DEFAULT nextval('public.cmdarg_cmdarg_id_seq'::regclass)
xtpos.pkgcmd.cmd_id cmdarg_cmd_id integer NOT NULL
cmdarg_order integer NOT NULL
cmdarg_arg text NOT NULL

Table xtpos.pkgcmdarg Inherits cmdarg,

Index - Schema xtpos


Table: xtpos.pkgimage

xtpos.pkgimage Structure
F-Key Name Type Description
image_id integer PRIMARY KEY DEFAULT nextval('public.image_image_id_seq'::regclass)
image_name text
image_descrip text
image_data text

Table xtpos.pkgimage Inherits image,

Index - Schema xtpos


Table: xtpos.pkgmetasql

xtpos.pkgmetasql Structure
F-Key Name Type Description
metasql_id integer PRIMARY KEY DEFAULT nextval('public.metasql_metasql_id_seq'::regclass)
metasql_group text
metasql_name text
metasql_notes text
metasql_query text
metasql_lastuser text
metasql_lastupdate date
metasql_grade integer NOT NULL

Table xtpos.pkgmetasql Inherits metasql,

Index - Schema xtpos


Table: xtpos.pkgpriv

xtpos.pkgpriv Structure
F-Key Name Type Description
priv_id integer PRIMARY KEY DEFAULT nextval('public.priv_priv_id_seq'::regclass)
priv_module text
priv_name text
priv_descrip text
priv_seq integer

Table xtpos.pkgpriv Inherits priv,

Index - Schema xtpos


Table: xtpos.pkgreport

xtpos.pkgreport Structure
F-Key Name Type Description
report_id integer PRIMARY KEY DEFAULT nextval('public.report_report_id_seq'::regclass)
report_name text
report_sys boolean
report_source text
report_descrip text
report_grade integer NOT NULL
report_loaddate timestamp without time zone

Table xtpos.pkgreport Inherits report,

Index - Schema xtpos


Table: xtpos.pkgscript

xtpos.pkgscript Structure
F-Key Name Type Description
script_id integer PRIMARY KEY DEFAULT nextval('public.script_script_id_seq'::regclass)
script_name text NOT NULL
script_order integer NOT NULL
script_enabled boolean NOT NULL DEFAULT false
script_source text NOT NULL
script_notes text

Table xtpos.pkgscript Inherits script,

Index - Schema xtpos


Table: xtpos.pkguiform

xtpos.pkguiform Structure
F-Key Name Type Description
uiform_id integer PRIMARY KEY DEFAULT nextval('public.uiform_uiform_id_seq'::regclass)
uiform_name text NOT NULL
uiform_order integer NOT NULL
uiform_enabled boolean NOT NULL DEFAULT false
uiform_source text NOT NULL
uiform_notes text

Table xtpos.pkguiform Inherits uiform,

Index - Schema xtpos


Table: xtpos.regdetail

Cash register detail

xtpos.regdetail Structure
F-Key Name Type Description
regdetail_id serial PRIMARY KEY

Cash register detail internal id and primary key
xtpos.reghist.reghist_id regdetail_reghist_id integer NOT NULL

Cash register detail cash register history id
regdetail_type character(1) NOT NULL

Indicates whether this transaction opened, closed, or adjusted the drawer value of a cash register
regdetail_startbal numeric NOT NULL

Cash register detail starting balance
regdetail_cashslsamt numeric NOT NULL

Cash register detail cash sales amount processed between current transaction and previous detail transaction
public.bankaccnt.bankaccnt_id regdetail_bankaccnt_id integer

Cash register detail transfer bank account id
regdetail_transferamt numeric NOT NULL

The amount (in base currency) transferred into or out of this register
regdetail_adjustamt numeric NOT NULL

The amount (in base currency) by which the drawer value of this register was adjusted
regdetail_endbal numeric NOT NULL

Cash register detail ending balance
regdetail_depchks boolean NOT NULL DEFAULT false

Flag indicating whether checks were deposited as part of this transaction
regdetail_notes text

Cash register detail notes
regdetail_time timestamp with time zone DEFAULT now()

Cash register detail time
regdetail_username text DEFAULT "current_user"()

The name of the user who performed this transaction
regdetail_journalnumber integer

The journal number used to record changes to the G/L for this transaction

 

xtpos.regdetail Constraints
Name Constraint
regdetail_regdetail_type_check CHECK ((regdetail_type = ANY (ARRAY['O'::bpchar, 'A'::bpchar, 'C'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.reghist

Cash Register History

xtpos.reghist Structure
F-Key Name Type Description
reghist_id serial PRIMARY KEY

Internal id and primary key
public.whsinfo.warehous_id reghist_warehous_id integer NOT NULL

Internal id of the site for this cash register
xtpos.terminal.terminal_id reghist_terminal_id integer NOT NULL

Internal id of the cash register terminal
reghist_taxauth_id integer

Deprecated - DO NOT USE
public.accnt.accnt_id reghist_asset_accnt_id integer NOT NULL

Internal id of the G/L asset account assigned to this cash register
public.accnt.accnt_id reghist_adjust_accnt_id integer NOT NULL

Internal id of the G/L adjustment account assigned to this cash register
public.accnt.accnt_id reghist_chkclr_accnt_id integer NOT NULL

Internal id of the G/L clearing account assigned to this cash register
reghist_open boolean NOT NULL DEFAULT true

Flag indicating whether this cash register was open at the time of this transaction
reghist_open_time timestamp with time zone NOT NULL DEFAULT now()

Time this cash register was last opened when this transaction occurred
reghist_close_time timestamp with time zone

Time this cash register was last closed when this transaction occurred

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.rtlsite

Information Retail Sites need to carry in addition to the standard Site (whsinfo) data

xtpos.rtlsite Structure
F-Key Name Type Description
rtlsite_id serial PRIMARY KEY

Internal id and primary key
public.whsinfo.warehous_id rtlsite_warehous_id integer UNIQUE NOT NULL

Internal id of the Site to which this additional data apply
rtlsite_quotedays integer NOT NULL DEFAULT 1

Number of days after which a quote created at this Retail Site expires
public.accnt.accnt_id rtlsite_asset_accnt_id integer NOT NULL

Internal id of the G/L asset account assigned to this Retail Site
public.accnt.accnt_id rtlsite_adjust_accnt_id integer NOT NULL

Internal id of the G/L adjustment account assigned to this Retail Site
public.accnt.accnt_id rtlsite_chkclr_accnt_id integer NOT NULL

Internal id of the G/L check clearning account assigned to this Retail Site
public.taxzone.taxzone_id rtlsite_taxzone_id integer

Internal id of the tax zone applied to this Retail Site

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.rtlsitebnkacct

List of which Bank Accounts may be used for cash register maintenance transactions by the various Retail Sites

xtpos.rtlsitebnkacct Structure
F-Key Name Type Description
rtlsitebnkacct_id serial PRIMARY KEY

Internal id and primary key
xtpos.rtlsite.rtlsite_id rtlsitebnkacct_rtlsite_id integer UNIQUE#1 NOT NULL

Internal id of the Retail Site
public.bankaccnt.bankaccnt_id rtlsitebnkacct_bankaccnt_id integer UNIQUE#1 NOT NULL

Internal id of the Bank Account

Index - Schema xtpos


Table: xtpos.rtlsiteterm

Association between a particular Cash Register Terminal and a particular Retail Site

xtpos.rtlsiteterm Structure
F-Key Name Type Description
rtlsiteterm_id serial PRIMARY KEY

Internal id and primary key
xtpos.rtlsite.rtlsite_id rtlsiteterm_rtlsite_id integer NOT NULL

Internal id of the Retail Site
xtpos.terminal.terminal_id rtlsiteterm_terminal_id integer UNIQUE NOT NULL

Internal id of the Cash Register Terminal

Index - Schema xtpos


Table: xtpos.salehead

Parent record of a single sale, which might contain one or more saleitems

xtpos.salehead Structure
F-Key Name Type Description
salehead_id serial PRIMARY KEY

Internal id and primary key
salehead_number text UNIQUE NOT NULL

Human-readable sale number
salehead_type character(1) NOT NULL

Indicator of whether this sale record is an actual sale, a quote, or
public.whsinfo.warehous_id salehead_warehous_id integer NOT NULL

Internal id of the Site at which this sale was made
public.custinfo.cust_id salehead_cust_id integer NOT NULL

Sale customer id
salehead_time timestamp with time zone NOT NULL DEFAULT now()

Time this sale was closed
xtpos.terminal.terminal_id salehead_terminal_id integer NOT NULL

Internal id of the cash register terminal on which this sale was made
public.salesrep.salesrep_id salehead_salesrep_id integer

Internal id of the sales rep who created this sale record
salehead_notes text

Sale notes
xtpos.reghist.reghist_id salehead_reghist_id integer

Register history record
salehead_closed boolean DEFAULT false

Flag indicating that this sale has been closed
salehead_checknumber text

Number of the check used to pay for this sale, if applicable
xtpos.regdetail.regdetail_id salehead_regdetail_id integer

Internal id of the register detail record in which this check was marked as deposited, if any
public.ccpay.ccpay_id salehead_ccpay_id integer

Internal id of the credit card payment record for this sale, if applicable
salehead_cashamt numeric

Amount of this sale paid in cash
salehead_checkamt numeric

Amount of this sale paid by check
public.taxzone.taxzone_id salehead_taxzone_id integer

Internal id for the tax zone applied

 

xtpos.salehead Constraints
Name Constraint
salehead_salehead_type_check CHECK ((salehead_type = ANY (ARRAY['S'::bpchar, 'Q'::bpchar, 'R'::bpchar])))

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.saleitem

Line item for a cash register sale

xtpos.saleitem Structure
F-Key Name Type Description
saleitem_id serial PRIMARY KEY

Internal id and primary key
xtpos.salehead.salehead_id saleitem_salehead_id integer UNIQUE#1 NOT NULL

Internal id of the parent sale record
saleitem_linenumber integer UNIQUE#1 NOT NULL

Sale item line number
public.itemsite.itemsite_id saleitem_itemsite_id integer NOT NULL

Internal id of the (item, site) pair - which item was sold and which site the inventory came from
saleitem_qty numeric NOT NULL

Sale item quantity
saleitem_unitprice numeric NOT NULL

Sale item unit price
public.taxtype.taxtype_id saleitem_taxtype_id integer

The type of tax that was charged for this line item (food tax vs. service tax vs. ...)
public.tax.tax_id saleitem_tax_id integer

Deprecated - DO NOT USE
saleitem_tax_pcta numeric

Deprecated - DO NOT USE
saleitem_tax_pctb numeric

Deprecated - DO NOT USE
saleitem_tax_pctc numeric

Deprecated - DO NOT USE
saleitem_tax_ratea numeric

Deprecated - DO NOT USE
saleitem_tax_rateb numeric

Deprecated - DO NOT USE
saleitem_tax_ratec numeric

Deprecated - DO NOT USE
public.invhist.invhist_id saleitem_invhist_id integer

Internal id of the inventory history record recording the sale of this line item

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Table: xtpos.saleitemtax

xtpos.saleitemtax Structure
F-Key Name Type Description
taxhist_id integer PRIMARY KEY DEFAULT nextval('public.taxhist_taxhist_id_seq'::regclass)
xtpos.saleitem.saleitem_id taxhist_parent_id integer NOT NULL
public.taxtype.taxtype_id taxhist_taxtype_id integer
public.tax.tax_id taxhist_tax_id integer NOT NULL
taxhist_basis numeric(16,2) NOT NULL
public.tax.tax_id taxhist_basis_tax_id integer
taxhist_sequence integer
taxhist_percent numeric(10,6) NOT NULL
taxhist_amount numeric(16,2) NOT NULL
taxhist_tax numeric(16,6) NOT NULL
taxhist_docdate date NOT NULL
taxhist_distdate date
taxhist_curr_id integer
taxhist_curr_rate numeric
taxhist_journalnumber integer

Table xtpos.saleitemtax Inherits taxhist,

Index - Schema xtpos


Table: xtpos.terminal

This table holds a list of cash register terminals defined for the xtpos package in xTuple ERP

xtpos.terminal Structure
F-Key Name Type Description
terminal_id serial PRIMARY KEY

Terminal internal id and primary key
terminal_number text UNIQUE NOT NULL

A human-readable short name for this cash register terminal, which must be unique for this database. If one database is shared by multiple stores, terminal numbers could include a prefix or suffix that distinguishes between those different stores.

Tables referencing this one via Foreign Key Constraints:

Index - Schema xtpos


Function: xtpos.cashregadjust(integer, integer, numeric, bpchar, boolean, numeric, bpchar, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTerminalId	ALIAS FOR $1;
  pBankAccntId	ALIAS FOR $2;
  _transferAmt	NUMERIC := COALESCE($3,0);
  pTransferDir	ALIAS FOR $4;
  pDepChecks	ALIAS FOR $5;
  _adjustAmt	NUMERIC := COALESCE($6,0);
  pAdjustDir	ALIAS FOR $7;
  pNotes	ALIAS FOR $8;
  _baglaccntid	INTEGER;
  _journal	INTEGER;
  _prevbal	NUMERIC;
  _rec	 	RECORD;
  _regdetailid	INTEGER;
  _reghistid	INTEGER;
  _sequence  	INTEGER;
  _test 	INTEGER := 0;
  
BEGIN  
  -- If no amounts, ignore
  IF (_transferAmt = 0 AND _adjustAmt = 0) THEN
    RAISE NOTICE 'No amount to process';
    
    RETURN 0;
    
  -- Validate
  ELSIF (_transferAmt < 0 OR _adjustAmt < 0) THEN
    RAISE EXCEPTION 'Negative amounts may not be entered';
  ELSIF (pTransferDir NOT IN ('I','O') OR pAdjustDir NOT IN ('I','O')) THEN
    RAISE EXCEPTION 'Invalid amount direction.  Valid directions are "I" (In) and "O" (Out)'; 
  END IF;
  
  -- Fetch history data
  SELECT reghist_id, reghist_asset_accnt_id, reghist_adjust_accnt_id,
    regdetail_endbal, terminal_number INTO _rec
  FROM xtpos.reghist
    JOIN xtpos.regdetail ON (reghist_id=regdetail_reghist_id)
    JOIN xtpos.terminal ON (reghist_terminal_id=terminal_id)
  WHERE ((terminal_id=pTerminalId)
   AND (reghist_open))
  ORDER BY regdetail_time DESC
  LIMIT 1;

  IF (FOUND) THEN
    _reghistid 	:= _rec.reghist_id;
    _prevbal	:= _rec.regdetail_endbal;
  ELSE
    --  Register closed, need to make a history record to record this against
    SELECT rtlsite_asset_accnt_id AS reghist_asset_accnt_id, 
      rtlsite_adjust_accnt_id AS reghist_adjust_accnt_id,
      rtlsite_chkclr_accnt_id AS reghist_chkclr_accnt_id,
      warehous_id, terminal_number INTO _rec
    FROM xtpos.rtlsiteterm
      JOIN xtpos.rtlsite ON (rtlsiteterm_rtlsite_id=rtlsite_id)
      JOIN xtpos.terminal ON (rtlsiteterm_terminal_id=terminal_id)
      JOIN whsinfo ON (rtlsite_warehous_id=warehous_id)
    WHERE (rtlsiteterm_terminal_id=pTerminalId);
  
    IF (FOUND) THEN
      _reghistid := nextval('reghist_reghist_id_seq');
    
      INSERT INTO xtpos.reghist (
        reghist_id,
        reghist_warehous_id,
        reghist_terminal_id,
        reghist_asset_accnt_id,
        reghist_adjust_accnt_id,
        reghist_chkclr_accnt_id,
        reghist_open,
        reghist_open_time,
        reghist_close_time )
      VALUES (
        _reghistid,
        _rec.warehous_id,
        pTerminalId,
        _rec.reghist_asset_accnt_id,
        _rec.reghist_adjust_accnt_id,
        _rec.reghist_chkclr_accnt_id,
        false,
        now(),
        now() );

      -- Fetch previous balance
      SELECT regdetail_endbal INTO _prevbal
      FROM xtpos.reghist
        JOIN xtpos.regdetail ON (reghist_id=regdetail_reghist_id)
      WHERE (reghist_terminal_id=pTerminalId)
      ORDER BY regdetail_time DESC
      LIMIT 1;
    ELSE
      RAISE EXCEPTION 'Retail Site not found';
    END IF;
  END IF;

  -- Fetch Bank Account G/L Account Id
  IF (pBankAccntId IS NOT NULL) THEN
    SELECT bankaccnt_accnt_id INTO _baglaccntid
    FROM xtpos.rtlsiteterm
      JOIN xtpos.rtlsite ON (rtlsite_id=rtlsiteterm_rtlsite_id)
      JOIN xtpos.rtlsitebnkacct ON (rtlsite_id=rtlsitebnkacct_rtlsite_id)
      JOIN bankaccnt ON (rtlsitebnkacct_bankaccnt_id=bankaccnt_id)
    WHERE ((bankaccnt_id=pBankAccntId)
     AND (rtlsiteterm_terminal_id=pTerminalId));

    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Bank Account not found for this retail site';
    END IF;
  ELSIF (pBankAcctId IS NULL AND COALESCE(pTransferAmt,0) > 0) THEN
    RAISE EXCEPTION 'Bank account must be provided to process transfer';
  END IF;

  IF (pAdjustDir = 'O') THEN
    _adjustAmt := _adjustAmt * -1;
  END IF;

  IF (pTransferDir = 'O') THEN
    _transferAmt := _transferAmt * -1;
  END IF;

  _journal	:= fetchJournalNumber('S/O');
  _sequence 	:= fetchGLSequence();

  --  Create deatil record for register history
  _regdetailid := nextval('regdetail_regdetail_id_seq');
  
  INSERT INTO xtpos.regdetail (
    regdetail_id,
    regdetail_reghist_id,
    regdetail_type,
    regdetail_startbal,
    regdetail_cashslsamt,
    regdetail_bankaccnt_id,
    regdetail_transferamt,
    regdetail_adjustamt,
    regdetail_endbal,
    regdetail_depchks,
    regdetail_username,
    regdetail_notes,
    regdetail_journalnumber )
  VALUES (
    _regdetailid,
    _reghistid,
    'A',
    _prevbal,
    0,
    pBankAccntId,
    _transferAmt,
    _adjustAmt,
    _prevbal + _transferAmt + _adjustAmt,
    false,
    current_user,
    pNotes,
    _journal );

  -- Record G/L transactions where applicable

  IF (pDepChecks) THEN
    PERFORM xtpos.depositChecks(_regdetailid, _journal);
  END IF;

  IF (_transferAmt != 0 AND _test >= 0) THEN
    SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _rec.terminal_number, _baglaccntid, 
      _transferAmt, current_date, 'Cash register bank transfer') INTO _test;
  END IF;

  IF (_adjustAmt != 0 AND _test >= 0)  THEN
    SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _rec.terminal_number, _rec.reghist_adjust_accnt_id, 
      _adjustAmt, current_date, 'Cash register adjustment') INTO _test;
  END IF;

  IF (_test >= 0) THEN
    SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _rec.terminal_number, _rec.reghist_asset_accnt_id, 
      (_transferAmt + _adjustAmt) * -1 , current_date, 'Cash register adjustment transaction') INTO _test;
  END IF;

  IF (_test >= 0) THEN
    SELECT postGLSeries(_sequence, _journal, false) INTO _test;
  END IF;

  IF (_test < 0) THEN
    RAISE EXCEPTION 'An error was encountered posting the g/l transaction.  Error:%',_test::text;
  END IF;
    
  RETURN _regdetailid;
END;

Function: xtpos.cashregclose(integer, integer, numeric, bpchar, numeric, bpchar, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTerminalId		ALIAS FOR $1;
  pBankAccntId		ALIAS FOR $2;
  _transferAmt		NUMERIC := COALESCE($3,0);
  pTransferDir		ALIAS FOR $4;
  _adjustAmt		NUMERIC := COALESCE($5,0);
  pAdjustDir		ALIAS FOR $6;
  pNotes		ALIAS FOR $7;
  _baglaccntid		INTEGER;
  _chkamt		NUMERIC;
  _cshamt     		NUMERIC;
  _ccBaglaccntid	INTEGER;
  _ccOrderDesc		TEXT;
  _journal		INTEGER;
  _noteSales		TEXT;
  _noteClose		TEXT;
  _rec	 		RECORD;
  _sale			RECORD;
  _regdetailid		INTEGER;
  _seqRev  		INTEGER;
  _seqCls		INTEGER;
  _taxBaseValue		NUMERIC;
  _test			INTEGER := 0;
  _cohistid		INTEGER;
  
BEGIN  
  -- Validate
  IF (_transferAmt < 0 OR _adjustAmt < 0) THEN
    RAISE EXCEPTION 'Negative amounts may not be entered';
  ELSIF (pTransferDir NOT IN ('I','O') OR pAdjustDir NOT IN ('I','O')) THEN
    RAISE EXCEPTION 'Invalid amount direction.  Valid directions are "I" (In) and "O" (Out)'; 
  
  -- Fetch set up data
  ELSE
    SELECT reghist_id, reghist_asset_accnt_id, reghist_adjust_accnt_id,
      reghist_chkclr_accnt_id, regdetail_endbal, terminal_number INTO _rec
    FROM xtpos.reghist
      JOIN xtpos.regdetail ON (reghist_id=regdetail_reghist_id)
      JOIN xtpos.terminal ON (reghist_terminal_id=terminal_id)
    WHERE ((reghist_terminal_id=pTerminalId)
     AND (reghist_open))
    ORDER BY regdetail_time DESC
    LIMIT 1;
    
    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Terminal register is not open';
    END IF;
  END IF;

  -- Fetch Bank Account G/L Account Id
  IF (pBankAccntId IS NOT NULL) THEN
    SELECT bankaccnt_accnt_id INTO _baglaccntid
    FROM xtpos.rtlsiteterm
      JOIN xtpos.rtlsite ON (rtlsite_id=rtlsiteterm_rtlsite_id)
      JOIN xtpos.rtlsitebnkacct ON (rtlsite_id=rtlsitebnkacct_rtlsite_id)
      JOIN bankaccnt ON (rtlsitebnkacct_bankaccnt_id=bankaccnt_id)
    WHERE ((bankaccnt_id=pBankAccntId)
     AND (rtlsiteterm_terminal_id=pTerminalId));

    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Bank Account not found for this retail site';
    END IF;
  ELSIF (pBankAccntId IS NULL AND _transferamt > 0) THEN
    RAISE EXCEPTION 'Bank account must be provided to process transfer';
  END IF;

  -- Determine sense
  IF (pAdjustDir = 'O') THEN
    _adjustAmt := _adjustAmt * -1;
  END IF;

  IF (pTransferDir = 'O') THEN
    _transferAmt := _transferAmt * -1;
  END IF;

  --  Get Credit card gl account.  When 7606 implemented, we'll
  --  Have to get an account for each credit card type
  SELECT bankaccnt_accnt_id INTO _ccBaglaccntid
  FROM bankaccnt
  WHERE (bankaccnt_id=fetchmetricvalue('CCDefaultBank')::INTEGER);

  -- Set some variables for G/L processing
  _journal	:= fetchJournalNumber('C/R');
  _seqRev 	:= fetchGLSequence();
  _seqCls	:= fetchGLSequence();
  _noteSales 	:= 'Sales posting for terminal ' || _rec.terminal_number;
  _noteClose	:= 'Close terminal ' || _rec.terminal_number;

  -- Post Sales
  FOR _sale IN
    SELECT
      salehead_cust_id, salehead_time,salehead_number, salehead_cashamt,
      salehead_checknumber, salehead_salesrep_id,
      saleitem_id, saleitem_unitprice, saleitem_qty, saleitem_taxtype_id,
      saleitem_itemsite_id, round(saleitem_unitprice * saleitem_qty,2) AS sale_amount,
      findSalesAccnt(saleitem_itemsite_id, 'IS', salehead_cust_id) AS sales_accnt_id,
      COALESCE(invhist_unitcost,0) AS unitcost,
      cust_name, addr_line1, addr_line2, addr_line3,
      addr_city, addr_state, addr_postalcode,
      COALESCE(salesrep_commission,0) AS commission
    FROM xtpos.reghist
      JOIN xtpos.salehead ON (reghist_id=salehead_reghist_id)
      JOIN xtpos.saleitem ON (salehead_id=saleitem_salehead_id)
      LEFT OUTER JOIN invhist ON (saleitem_invhist_id=invhist_id)
      LEFT OUTER JOIN custinfo ON (salehead_cust_id=cust_id)
      LEFT OUTER JOIN cntct ON (cust_cntct_id=cntct_id)
      LEFT OUTER JOIN addr ON (cntct_addr_id=addr_id)
      LEFT OUTER JOIN salesrep ON (salehead_salesrep_id=salesrep_id)
    WHERE (salehead_reghist_id=_rec.reghist_id)
  LOOP
    IF (_test >= 0) THEN

      -- Credit revenue
      IF (_sale.sale_amount <> 0) THEN
        SELECT insertIntoGLSeries( _seqRev, 'S/O', 'RS', _rec.terminal_number, 
	    salesaccnt_sales_accnt_id, _sale.sale_amount, 
	    current_date, _noteSales) INTO _test
	FROM salesaccnt
	WHERE (salesaccnt_id=_sale.sales_accnt_id);
      END IF;

      -- Credit tax accounts
      PERFORM addTaxToGLSeries(_seqRev, 
	   'S/O', 'RS', _rec.terminal_number,
	   basecurrid(),
	   current_date, current_date,
	   'saleitemtax', _sale.saleitem_id, _noteSales);

      UPDATE xtpos.saleitemtax
      SET taxhist_journalnumber = _journal
      WHERE (taxhist_parent_id=_sale.saleitem_id);

      -- Record sales history
      SELECT nextval('cohist_cohist_id_seq') INTO _cohistid;
      INSERT INTO cohist
      ( cohist_id,cohist_cust_id, cohist_itemsite_id, 
        cohist_shipdate, cohist_shipvia, cohist_invcdate,
        cohist_ordernumber, cohist_orderdate, cohist_doctype,
        cohist_qtyshipped, cohist_unitprice, cohist_unitcost,
        cohist_salesrep_id, cohist_commission, cohist_commissionpaid,
        cohist_billtoname, cohist_billtoaddress1,
        cohist_billtoaddress2, cohist_billtoaddress3,
        cohist_billtocity, cohist_billtostate, cohist_billtozip,
        cohist_sequence, cohist_taxtype_id)
      VALUES
      ( _cohistid,_sale.salehead_cust_id, _sale.saleitem_itemsite_id, 
        _sale.salehead_time::date, 'Retail Sale', _sale.salehead_time::date,
        _sale.salehead_number, _sale.salehead_time, 'R',
        _sale.saleitem_qty, _sale.saleitem_unitprice, _sale.unitcost,
        _sale.salehead_salesrep_id, (_sale.commission * _sale.sale_amount), FALSE,
        _sale.cust_name, _sale.addr_line1,
        _sale.addr_line2, _sale.addr_line3,
        _sale.addr_city, _sale.addr_state, _sale.addr_postalcode,
        _seqRev, _sale.saleitem_taxtype_id);
        
        INSERT INTO cohisttax
        ( taxhist_parent_id, taxhist_taxtype_id, taxhist_tax_id,
          taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
          taxhist_percent, taxhist_amount, taxhist_tax,
          taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
          taxhist_journalnumber )
        SELECT _cohistid, taxhist_taxtype_id, taxhist_tax_id,
           taxhist_basis, taxhist_basis_tax_id, taxhist_sequence,
           taxhist_percent, taxhist_amount, taxhist_tax,
           taxhist_docdate, taxhist_distdate, taxhist_curr_id, taxhist_curr_rate,
           taxhist_journalnumber
        FROM xtpos.saleitemtax
        WHERE (taxhist_parent_id=_sale.saleitem_id);
    END IF;
  END LOOP;

  -- Debit register for cash received
  _cshamt := xtpos.reghistsales(_rec.reghist_id,'S');
  
  IF (_test >= 0) THEN
    SELECT insertIntoGLSeries( _seqRev, 'S/O', 'RS', _rec.terminal_number, 
	_rec.reghist_asset_accnt_id, _cshamt * -1, 
	current_date, _noteSales) INTO _test;
  END IF;

  -- Debit check clearing for checks
  _chkamt := xtpos.reghistsales(_rec.reghist_id,'K');
  
  IF (_test >= 0) THEN
    SELECT insertIntoGLSeries( _seqRev, 'S/O', 'RS', _rec.terminal_number, 
	_rec.reghist_chkclr_accnt_id, _chkamt * -1, 
	current_date, _noteSales) INTO _test;
  END IF;

  -- Loop through credit card sales headers and debit CC Account for each trans
  FOR _sale IN
    SELECT
      ccard_type, ccpay_order_number, ccpay_order_number_seq,
      ccpay_amount * CASE WHEN(salehead_type='R') THEN 1 ELSE -1 END AS ccpay_amount,
      CASE WHEN (salehead_type='R') THEN findARAccount(ccpay_cust_id)
           ELSE findPrepaidAccount(ccpay_cust_id)
      END AS accnt
    FROM xtpos.salehead, ccpay, ccard
    WHERE ((salehead_reghist_id=_rec.reghist_id)
     AND (salehead_ccpay_id=ccpay_id)
     AND (ccpay_ccard_id=ccard_id))
  LOOP
    _ccOrderDesc := (_sale.ccard_type || '-' || _sale.ccpay_order_number::TEXT ||
		   '-' || _sale.ccpay_order_number_seq::TEXT);
    SELECT insertIntoGLSeries( _seqRev, 'S/O', 'RS', _ccOrderDesc, 
	   _sale.accnt, _sale.ccpay_amount, current_date, 
	  _noteSales) INTO _test;
  END LOOP;

  --  Create deatil record for register history
  _regdetailid := nextval('regdetail_regdetail_id_seq');
  
  INSERT INTO xtpos.regdetail (
    regdetail_id,
    regdetail_reghist_id,
    regdetail_type,
    regdetail_startbal,
    regdetail_cashslsamt,
    regdetail_bankaccnt_id,
    regdetail_transferamt,
    regdetail_adjustamt,
    regdetail_endbal,
    regdetail_depchks,
    regdetail_username,
    regdetail_notes,
    regdetail_journalnumber )
  VALUES (
    _regdetailid,
    _rec.reghist_id,
    'C',
    _rec.regdetail_endbal,
    _cshamt,
    pBankAccntId,
    _transferAmt,
    _adjustAmt,
    _rec.regdetail_endbal + _cshamt + _transferAmt + _adjustAmt,
    false,
    current_user,
    pNotes,
    _journal );

  -- Deposit checks
  PERFORM xtpos.depositChecks(_regdetailid, _journal);
  
  -- Post Transfers and adjustments
  IF (_transferAmt != 0 AND _test >=0) THEN
    SELECT insertIntoGLSeries( _seqCls, 'S/O', 'MR', _rec.terminal_number, _baglaccntid, 
      _transferAmt, current_date, _noteClose) INTO _test;
  END IF;

  IF (_adjustAmt != 0 AND _test >= 0) THEN
    SELECT insertIntoGLSeries( _seqCls, 'S/O', 'MR', _rec.terminal_number, _rec.reghist_adjust_accnt_id, 
      _adjustAmt, current_date, _noteClose) INTO _test;
  END IF;

  IF (_test >= 0) THEN
    SELECT insertIntoGLSeries( _seqCls, 'S/O', 'MR', _rec.terminal_number, _rec.reghist_asset_accnt_id, 
      (_transferAmt + _adjustAmt) * -1 , current_date, _noteClose ) INTO _test;
  END IF;

  IF (_test >= 0) THEN
    SELECT postGLSeries(_seqRev, _journal, false) INTO _test;
  END IF;

  IF (_test >= 0) THEN
    SELECT postGLSeries(_seqCls, _journal, false) INTO _test;
  END IF;

  IF (_test < 0) THEN
    RAISE EXCEPTION 'An error was encountered posting the g/l transaction.  Error:%',_test::text;
  END IF;

  -- Purge pending sales for this register
  DELETE FROM salehead 
  WHERE ((salehead_terminal_id=pTerminalId)
  AND (salehead_type IN ('S','R'))
  AND (NOT salehead_closed));

  -- Close register session
  UPDATE reghist SET
    reghist_open=false,
    reghist_close_time=now()
  WHERE (reghist_id=_rec.reghist_id);
    
  RETURN _regdetailid;
END;

Function: xtpos.cashregopen(integer, integer, numeric, bpchar, numeric, bpchar, text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTerminalId	ALIAS FOR $1;
  pBankAccntId	ALIAS FOR $2;
  _transferAmt	NUMERIC := COALESCE($3,0);
  pTransferDir	ALIAS FOR $4;
  _adjustAmt	NUMERIC := COALESCE($5,0);
  pAdjustDir	ALIAS FOR $6;
  pNotes	ALIAS FOR $7;
  _baglaccntid	INTEGER;
  _def		RECORD;
  _journal	INTEGER;
  _noteOpen	TEXT;
  _prevbal      NUMERIC;
  _regdetailid	INTEGER;
  _reghistid 	INTEGER;
  _sequence  	INTEGER;
  _test		INTEGER := 0;
  
BEGIN  
  -- Validate
  IF (_transferAmt < 0 OR _adjustAmt < 0) THEN
    RAISE EXCEPTION 'Negative amounts may not be entered';
  ELSIF (pTransferDir NOT IN ('I','O') OR pAdjustDir NOT IN ('I','O')) THEN
    RAISE EXCEPTION 'Invalid amount direction.  Valid directions are "I" (In) and "O" (Out)'; 
    
  -- Check to make sure register is not already open
  ELSIF (SELECT (count(reghist_id) > 0) 
      FROM xtpos.reghist
      WHERE ((reghist_terminal_id=pTerminalId)
      AND (reghist_open))) THEN
    RAISE EXCEPTION 'Terminal register is already open';
    
  -- Fetch Bank Account G/L Account Id
  ELSIF (pBankAccntId IS NOT NULL) THEN
    SELECT bankaccnt_accnt_id INTO _baglaccntid
    FROM xtpos.rtlsiteterm
      JOIN xtpos.rtlsite ON (rtlsite_id=rtlsiteterm_rtlsite_id)
      JOIN xtpos.rtlsitebnkacct ON (rtlsite_id=rtlsitebnkacct_rtlsite_id)
      JOIN bankaccnt ON (rtlsitebnkacct_bankaccnt_id=bankaccnt_id)
    WHERE ((bankaccnt_id=pBankAccntId)
     AND (rtlsiteterm_terminal_id=pTerminalId));

    IF (NOT FOUND) THEN
      RAISE EXCEPTION 'Bank Account not found for this retail site';
    END IF;
  ELSIF (pBankAccntId IS NULL AND _transferamt > 0) THEN
    RAISE EXCEPTION 'Bank account must be provided to process transfer';
  END IF;

  IF (pAdjustDir = 'O') THEN
    _adjustAmt := _adjustAmt * -1;
  END IF;

  IF (pTransferDir = 'O') THEN
    _transferAmt := _transferAmt * -1;
  END IF;
  
  -- Fetch retail site record and corresponding data 
  SELECT rtlsite_asset_accnt_id, rtlsite_adjust_accnt_id,
         rtlsite_chkclr_accnt_id,
         warehous_id,
         terminal_number INTO _def
  FROM xtpos.rtlsite
    JOIN whsinfo ON (rtlsite_warehous_id=warehous_id)
    JOIN xtpos.rtlsiteterm ON (rtlsite_id=rtlsiteterm_rtlsite_id)
    JOIN xtpos.terminal ON (terminal_id=rtlsiteterm_terminal_id)
  WHERE (terminal_id=pTerminalId);
  
  IF (FOUND) THEN
    _reghistid := nextval('reghist_reghist_id_seq');
    
    INSERT INTO xtpos.reghist (
      reghist_id,
      reghist_warehous_id,
      reghist_terminal_id,
      reghist_asset_accnt_id,
      reghist_adjust_accnt_id,
      reghist_chkclr_accnt_id,
      reghist_open,
      reghist_open_time )
    VALUES (
      _reghistid,
      _def.warehous_id,
      pTerminalId,
      _def.rtlsite_asset_accnt_id,
      _def.rtlsite_adjust_accnt_id,
      _def.rtlsite_chkclr_accnt_id,
      true,
      now() );
  ELSE
    RAISE EXCEPTION 'Retail Site Terminal not found';
  END IF;

  -- Fetch previous balance
  SELECT regdetail_endbal INTO _prevbal
  FROM xtpos.reghist
    JOIN xtpos.regdetail ON (reghist_id=regdetail_reghist_id)
  WHERE (reghist_terminal_id=pTerminalId)
  ORDER BY regdetail_time DESC
  LIMIT 1;

  -- Record G/L transactions if applicable
  IF (_transferAmt != 0 OR _adjustAmt != 0) THEN
    _noteOpen	:= 'Open posting for terminal ' || _def.terminal_number;
    _sequence 	:= fetchGLSequence();
    _journal	:= fetchJournalNumber('S/O');

    IF (_transferAmt != 0 AND _test >=0) THEN
      SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _def.terminal_number, _baglaccntid, 
        _transferAmt, current_date, _noteOpen) INTO _test;
    END IF;

    IF (_adjustAmt != 0 AND _test >=0) THEN
      SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _def.terminal_number, _def.rtlsite_adjust_accnt_id, 
        _adjustAmt, current_date, _noteOpen) INTO _test;     
    END IF;

    IF (_test >= 0) THEN
      SELECT insertIntoGLSeries( _sequence, 'S/O', 'MR', _def.terminal_number, _def.rtlsite_asset_accnt_id, 
        (_transferAmt + _adjustAmt) * -1 , current_date, _noteOpen) INTO _test;
    END IF;

    IF (_test >= 0) THEN
      SELECT postGLSeries(_sequence, _journal, false) INTO _test;
    END IF;
  END IF;

  IF (_test < 0) THEN
    RAISE EXCEPTION 'An error was encountered posting the g/l transaction.  Error:%',_test::text;
  END IF;

  --  Create deatil record for register history
  _regdetailid := nextval('regdetail_regdetail_id_seq');
  
  INSERT INTO xtpos.regdetail (
    regdetail_id,
    regdetail_reghist_id,
    regdetail_type,
    regdetail_startbal,
    regdetail_cashslsamt,
    regdetail_bankaccnt_id,
    regdetail_transferamt,
    regdetail_adjustamt,
    regdetail_endbal,
    regdetail_depchks,
    regdetail_username,
    regdetail_notes,
    regdetail_journalnumber )
  VALUES (
    _regdetailid,
    _reghistid,
    'O',
    COALESCE(_prevbal,0),
    0,
    pBankAccntId,
    _transferAmt,
    _adjustAmt,
    COALESCE(_prevbal,0) + _transferAmt + _adjustAmt,
    false,
    current_user,
    pNotes,
    _journal );
    
  RETURN _regdetailid;
END;

Function: xtpos.checkstatus(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId ALIAS FOR $1;
  _rec		RECORD;
  _expires	DATE;
  _closed	BOOLEAN;
BEGIN
  SELECT salehead_type, salehead_time, salehead_closed, salehead_warehous_id INTO _rec
  FROM xtpos.salehead
  WHERE (salehead_id=pSaleheadId);

  IF (FOUND) THEN
    IF ((_rec.salehead_type = 'Q') AND (NOT _rec.salehead_closed)) THEN
      SELECT (current_date - rtlsite_quotedays) INTO _expires
      FROM xtpos.rtlsite
      WHERE (rtlsite_warehous_id=_rec.salehead_warehous_id);

      IF (FOUND) THEN
        _closed := (_rec.salehead_time < _expires);
      ELSE
        _closed := true;
      END IF;

      IF (_closed) THEN
        UPDATE xtpos.salehead SET
          salehead_closed = true
        WHERE (salehead_id=pSaleheadId);
      END IF;
    ELSE
      _closed := _rec.salehead_closed;
    END IF;
  ELSE
    RAISE EXCEPTION 'Sale not found.';
  END IF;

  RETURN _closed;
END;

Function: xtpos.depositchecks(integer, integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pRegdetailId 		ALIAS FOR $1;
  pJournalNumber	ALIAS FOR $2;
  _rec			RECORD;
  _amt			NUMERIC := 0;
  _noteDeposit		TEXT;
  _seq			INTEGER;
  _test			INTEGER := 0;
  
BEGIN    

  _seq		:= fetchGLSequence();
    
  -- Loop through undeposited checks on this register session
  FOR _rec IN 
  SELECT
    salehead_id, salehead_number, salehead_cashamt, salehead_checkamt,
    salehead_checknumber,salehead_cust_id, regdetail_bankaccnt_id, 
    reghist_chkclr_accnt_id, terminal_number, bankaccnt_accnt_id
  FROM  xtpos.regdetail
    JOIN xtpos.reghist ON (reghist_id=regdetail_reghist_id)
    JOIN xtpos.salehead ON ((salehead_reghist_id=reghist_id)
			  AND (salehead_checkamt > 0)
                         AND (salehead_regdetail_id IS NULL))
    JOIN terminal ON (reghist_terminal_id=terminal_id)
    JOIN bankaccnt ON (bankaccnt_id=regdetail_bankaccnt_id)
  WHERE (regdetail_id=pRegdetailId)
  LOOP
    _noteDeposit 	:= 'Check deposit for terminal ' || _rec.terminal_number;
    
--  Record the check application
    INSERT INTO arapply
    ( arapply_cust_id,
      arapply_source_aropen_id, arapply_source_doctype, arapply_source_docnumber,
      arapply_target_aropen_id, arapply_target_doctype, arapply_target_docnumber,
      arapply_fundstype, arapply_refnumber,
      arapply_applied, arapply_closed,
      arapply_postdate, arapply_distdate, arapply_journalnumber, arapply_username,
      arapply_curr_id )
    VALUES
    ( _rec.salehead_cust_id,
      -1, 'K', '', 
      -1, 'Point of Sale', _rec.salehead_number,
      'C', _rec.salehead_checknumber,
      _rec.salehead_checkamt, TRUE,
      CURRENT_DATE, current_date, pJournalNumber, CURRENT_USER, basecurrid() );

    -- Debit bank account
    SELECT insertIntoGLSeries( _seq, 'S/O', 'RS',
	'C-'|| _rec.salehead_checknumber, _rec.bankaccnt_accnt_id,
        _rec.salehead_checkamt * -1, current_date, _noteDeposit) INTO _test;

    IF (_test < 0) THEN
      RAISE EXCEPTION 'An error was encountered posting the g/l transaction.  Error:%',_test::text;
    END IF;

    _amt := _amt + _rec.salehead_checkamt;
    
    --  Update the sale that this check is being cleared
    
    UPDATE salehead SET
      salehead_regdetail_id=pRegdetailId
    WHERE (salehead_id=_rec.salehead_id);

  END LOOP;
  
  -- Credit check clearing
  IF (_amt > 0) THEN
    SELECT insertIntoGLSeries( _seq, 'S/O', 'RS', _rec.terminal_number, 
	_rec.reghist_chkclr_accnt_id, _amt, current_date, _noteDeposit) INTO _test;

    IF (_test < 0) THEN
      RAISE EXCEPTION 'An error was encountered posting the g/l transaction.  Error:%',_test::text;
    END IF;
  END IF;

  IF (_test >= 0) THEN
    SELECT postGLSeries(_seq, pJournalNumber, false) INTO _test;
  END IF;

  RETURN _amt;
          
END;

Function: xtpos.fetchsalenumber()

Returns: text

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _saleNumber TEXT;
  _test INTEGER;

BEGIN

  LOOP

    _saleNumber := nextval('sale_number_seq');

    SELECT salehead_id INTO _test
    FROM xtpos.salehead
    WHERE (salehead_number=_saleNumber);

    IF (NOT FOUND) THEN
      EXIT;
    END IF;

  END LOOP;

  RETURN _saleNumber;

END;

Function: xtpos.getrtlsiteid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSiteCode ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSiteCode IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT rtlsite_id INTO _returnVal
  FROM xtpos.rtlsite, whsinfo
  WHERE ((rtlsite_warehous_id=warehous_id)
  AND (warehous_code=pSiteCode));

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Retail Site for % not found.', pSiteCode;
  END IF;

  RETURN _returnVal;
END;

Function: xtpos.getsaleheadid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleNumber ALIAS FOR $1;
  _returnVal INTEGER;
BEGIN
  IF (pSaleNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT salehead_id INTO _returnVal
  FROM xtpos.salehead
  WHERE (salehead_number=pSaleNumber);

  IF (_returnVal IS NULL) THEN
	RAISE EXCEPTION 'Sale Number % not found.', pSaleNumber;
  END IF;

  RETURN _returnVal;
END;

Function: xtpos.getterminalid(text)

Returns: integer

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pTerminalNumber 	ALIAS FOR $1;
  _returnVal 		INTEGER;
BEGIN
  IF (pTerminalNumber IS NULL) THEN
	RETURN NULL;
  END IF;

  SELECT terminal_id INTO _returnVal
  FROM xtpos.terminal
  WHERE (terminal_number=UPPER(pTerminalNumber));

  IF (_returnVal IS NULL) THEN
	_returnVal := nextval('terminal_terminal_id_seq');

	INSERT INTO terminal (terminal_id, terminal_number)
	VALUES (_returnVal, UPPER(pTerminalNumber));
  END IF;

  RETURN _returnVal;
END;

Function: xtpos.itemprice(integer, integer, numeric)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pItemid ALIAS FOR $1;
  pCustid ALIAS FOR $2;
  pQty ALIAS FOR $3;

BEGIN
  RETURN itemPrice(pItemid, pCustid, -1, pQty, baseCurrId(), CURRENT_DATE);
END;

Function: xtpos.postsaleinv(integer)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId 		ALIAS FOR $1;
  _invhistid		INTEGER;
  _itemlocseries	INTEGER := nextval('itemloc_series_seq');
  _sale			RECORD;
  
BEGIN  
  -- Post inventory
  FOR _sale IN
    SELECT salehead_number, salehead_cust_id, 
      saleitem_id, saleitem_qty, 
      itemsite_id, itemsite_controlmethod, 
      costcat_asset_accnt_id,
      item_number, item_type
    FROM xtpos.salehead
      JOIN xtpos.saleitem ON (salehead_id=saleitem_salehead_id)
      JOIN itemsite ON (saleitem_itemsite_id=itemsite_id)
      JOIN item ON (itemsite_item_id=item_id)
      JOIN costcat ON (itemsite_costcat_id=costcat_id)
    WHERE (saleitem_salehead_id=pSaleheadId)
  LOOP
    IF (_sale.itemsite_controlmethod IN ('L','S')) THEN
      RAISE EXCEPTION 'Lot/Serial controlled items are not supported by the retail module at this time';
    ELSIF (_sale.item_type = 'J') THEN
      RAISE EXCEPTION 'Job items are not supported by the retail module.';
    ELSIF (_sale.itemsite_controlmethod = 'R') THEN

      SELECT postInvTrans( _sale.itemsite_id, 'RS', _sale.saleitem_qty * -1,
  			   'S/O', 'RS',
			   _sale.salehead_number, _sale.salehead_number, 
			   'Item Sale: ' || _sale.item_number,
			   _sale.costcat_asset_accnt_id,
			   resolveCOSAccount(_sale.itemsite_id, _sale.salehead_cust_id), 
			   _itemlocSeries, now() ) INTO _invhistid;

      IF (_invhistid < 0) THEN
        RAISE EXCEPTION 'An error occurred processing an inventory transaction.  Error:%', _invhistid;
      ELSE
        PERFORM postItemlocseries(_itemlocSeries);
        
        UPDATE xtpos.saleitem SET
          saleitem_invhist_id=_invhistid
        WHERE (saleitem_id=_sale.saleitem_id);
      END IF;
    END IF;
  END LOOP;
  
  RETURN true;
END;

Function: xtpos.reghistsales(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pReghistId 	ALIAS FOR $1;
  _returnVal	NUMERIC;
BEGIN
  SELECT xtpos.reghistSales(pReghistId, NULL) INTO _returnVal;
  
  RETURN _returnVal;
END;

Function: xtpos.reghistsales(integer, text)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pReghistId 	ALIAS FOR $1;
  pType		ALIAS FOR $2;
  _totalSales  	NUMERIC;
  _creditSales	NUMERIC;
  _checkSales	NUMERIC;
  _returnVal	NUMERIC;

BEGIN
  -- Validate
  IF (pReghistId IS NULL) THEN
    RETURN 0;
  ELSIF (pType NOT IN (NULL,'S','K','C')) THEN
    RAISE EXCEPTION 'Invalid sale type % passed.  Valid types are NULL, "S" (cash), "K" (check), "C" (credit)',pType;
  END IF;
  
  -- Fetch values
  IF (pType IS NULL OR pType = 'S') THEN
    -- Sum of all sales
    SELECT COALESCE(SUM(sale + xtpos.saletax(salehead_id)),0) INTO _totalSales
    FROM
      (SELECT 
        salehead_id,
        COALESCE(SUM(round(saleitem_qty * saleitem_unitprice,2)),0) AS sale
       FROM xtpos.salehead
        JOIN xtpos.reghist ON ((salehead_reghist_id=reghist_id) 
                           AND (reghist_id=pReghistId))
        JOIN xtpos.saleitem ON (saleitem_salehead_id=salehead_id)
      WHERE (salehead_closed)
      GROUP BY salehead_id) sales;
  END IF;

  IF (pType IS NULL) THEN
    _returnVal := _totalSales;
  ELSE
    -- Sum of non cash sales
    SELECT COALESCE(SUM(salehead_checkamt),0), COALESCE(SUM(COALESCE(ccpay_amount,0) * CASE WHEN(salehead_type='R') THEN -1 ELSE 1 END),0) INTO _checkSales,_creditSales
    FROM xtpos.salehead
      JOIN xtpos.reghist ON ((salehead_reghist_id=reghist_id) 
                          AND (reghist_id=pReghistId))
      LEFT OUTER JOIN ccpay ON (salehead_ccpay_id=ccpay_id)
      WHERE (salehead_closed);

    IF (pType = 'S') THEN
      _returnVal := _totalSales - _creditSales - _checkSales;
    ELSIF (pType = 'C') THEN
      _returnVal := _creditSales;
    ELSE
      _returnVal := _checkSales;
    END IF;
  END IF;
  
  RETURN _returnVal;
END;

Function: xtpos.rtlsitestatuscheck()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _t   		RECORD;
  _endbal	NUMERIC;
BEGIN
  -- Make sure terminal isn't open
  IF (SELECT (count(reghist_id) > 1)
      FROM xtpos.reghist
      WHERE ((reghist_warehous_id=OLD.rtlsite_warehous_id)
       AND (reghist_open))) THEN
    RAISE EXCEPTION 'Retail Site may not be deleted when one or more registers are open';
  END IF;

  -- Make sure there's no money in one of the registers
  FOR _t IN
    SELECT rtlsiteterm_terminal_id
    FROM xtpos.rtlsiteterm
    WHERE (rtlsiteterm_rtlsite_id=OLD.rtlsite_id)
  LOOP
    SELECT regdetail_endbal INTO _endbal
    FROM xtpos.reghist
      JOIN xtpos.regdetail ON (reghist_id=regdetail_reghist_id)
    WHERE ((reghist_warehous_id=OLD.rtlsite_warehous_id)
    AND (reghist_terminal_id=_t.rtlsiteterm_terminal_id))
    ORDER BY regdetail_time DESC
    LIMIT 1;

    IF (FOUND) THEN
      IF (_endbal > 0) THEN
        RAISE EXCEPTION 'Retail Site may not be deleted when one or more registers has an outstanding balance';
      END IF;
    END IF;
  END LOOP;

  RETURN OLD;
END;

Function: xtpos.rtlsitetermstatuscheck()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _endbal	NUMERIC;
BEGIN
  -- Make sure terminal isn't open
  IF (SELECT (count(reghist_id) > 1)
      FROM xtpos.reghist
      WHERE ((reghist_terminal_id=OLD.rtlsiteterm_terminal_id)
       AND (reghist_open))) THEN
    RAISE EXCEPTION 'Terminal % may not be disassociated from retail site while it is open', OLD.terminal_number;
  END IF;

  -- Make sure there's no money in the register
  SELECT regdetail_endbal INTO _endbal
  FROM xtpos.regdetail
    JOIN xtpos.reghist ON (reghist_id=regdetail_reghist_id)
  WHERE (reghist_terminal_id=OLD.rtlsiteterm_terminal_id)
  ORDER BY regdetail_time DESC
  LIMIT 1;

  IF (FOUND) THEN
    IF (_endbal > 0) THEN
      RAISE EXCEPTION 'Terminal may not be deleted when it has an outstanding balance';
    END IF;
  END IF;

  RETURN OLD;
END;

Function: xtpos.saleclosecash(integer, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId 	ALIAS FOR $1;
  pTendered	ALIAS FOR $2;
  _rec		RECORD;
  _amount	NUMERIC;
  
BEGIN  
  -- Sum sale and fetch register history record to bind sale to
  SELECT sum(round(saleitem_qty * saleitem_unitprice, 2)) + xtpos.saletax(salehead_id) AS saleamt,
    reghist_id, salehead_closed, salehead_type INTO _rec
  FROM xtpos.salehead
   JOIN xtpos.saleitem ON (salehead_id=saleitem_salehead_id)
   JOIN xtpos.reghist 	ON ((reghist_terminal_id=salehead_terminal_id)
			AND (reghist_open))
  WHERE (salehead_id=pSaleheadId)
  GROUP BY reghist_id, salehead_closed, salehead_type, salehead_id;

  IF (FOUND) THEN
    -- Check status
    IF (_rec.salehead_closed) THEN
      RAISE EXCEPTION 'The sale is already closed.';
    -- Check amount
    ELSIF (pTendered < _rec.saleamt) THEN
      RAISE EXCEPTION 'The tendered amout % is less than the sale amount of %.', pTendered::text, _rec.saleamt::text;
    ELSIF (_rec.salehead_type = 'Q') THEN
      RAISE EXCEPTION 'Can not record payment against a Quote.';
    END IF;

    -- Post inventory
    PERFORM xtpos.postSaleInv(pSaleheadId);

    IF (_rec.salehead_type = 'R') THEN
      _amount := pTendered * -1;
    ELSE
      _amount := pTendered;
    END IF;
    
    -- Close the sale
    UPDATE xtpos.salehead SET
      salehead_closed=true,
      salehead_time=now(),
      salehead_cashamt=_amount,
      salehead_reghist_id=_rec.reghist_id
    WHERE (salehead_id=pSaleheadId);
  ELSE
    RAISE EXCEPTION 'Register is not open';
  END IF;
  
  RETURN true;
END;

Function: xtpos.saleclosecheck(integer, text, numeric, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId 	ALIAS FOR $1;
  pCheckNumber	ALIAS FOR $2;
  pCheckAmt	ALIAS FOR $3;
  pTendered	ALIAS FOR $4;
  _rec		RECORD;
  
BEGIN    
  -- Find the open register history record to bind sale to
  SELECT reghist_id, salehead_closed, salehead_type INTO _rec
  FROM xtpos.salehead
   JOIN xtpos.reghist 	ON ((reghist_terminal_id=salehead_terminal_id)
			AND (reghist_open))
  WHERE (salehead_id=pSaleheadId);

  IF (FOUND) THEN
    IF (_rec.salehead_closed) THEN
      RAISE EXCEPTION 'Sale is already closed.';
    ELSIF (_rec.salehead_type IN ('Q','R')) THEN
      RAISE EXCEPTION 'Checks may not be processed against Quotes or Returns.';
    END IF;
    
     -- Post inventory
     PERFORM xtpos.postSaleInv(pSaleheadId);
  
    -- Close the sale
    UPDATE xtpos.salehead SET
      salehead_closed=true,
      salehead_time=now(),
      salehead_checknumber=pCheckNumber,
      salehead_checkamt=pCheckAmt,
      salehead_cashamt=pTendered,
      salehead_reghist_id=_rec.reghist_id
    WHERE (salehead_id=pSaleheadId);
  ELSE
    RAISE EXCEPTION 'Register is not open';
  END IF;
  
  RETURN true;
END;

Function: xtpos.saleclosecredit(integer, integer, numeric)

Returns: boolean

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId 	ALIAS FOR $1;
  pCcpayId	ALIAS FOR $2;
  pTendered    	ALIAS FOR $3;
  _rec		RECORD;
  _amount	NUMERIC;
  
BEGIN  
  -- Find the open register history record to bind sale to
  SELECT reghist_id, salehead_closed, salehead_type INTO _rec
  FROM xtpos.salehead
   JOIN xtpos.reghist 	ON ((reghist_terminal_id=salehead_terminal_id)
			AND (reghist_open))
  WHERE (salehead_id=pSaleheadId);

  IF (FOUND) THEN
    IF (_rec.salehead_closed) THEN
      RAISE EXCEPTION 'Sale is already closed.';
    ELSIF (_rec.salehead_type = 'Q') THEN
      RAISE EXCEPTION 'Can not record payment against a Quote.';
    END IF;
    
    -- Post inventory
    PERFORM postSaleInv(pSaleheadId);

    IF (_rec.salehead_type = 'R') THEN
      _amount := pTendered * -1;
    ELSE
      _amount := pTendered;
    END IF;
    
    -- Close the sale
    UPDATE xtpos.salehead SET
      salehead_closed=true,
      salehead_time=now(),
      salehead_cashamt=_amount,
      salehead_ccpay_id=pCcpayId,
      salehead_reghist_id=_rec.reghist_id
    WHERE (salehead_id=pSaleheadId);
  ELSE
    RAISE EXCEPTION 'Register is not open';
  END IF;
  
  RETURN true;
END;

Function: xtpos.saleheadprivcheck()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  -- Privilege Checks
  IF (NOT checkPrivilege('MaintainRetailSales')) THEN
    RAISE EXCEPTION 'You do not have privileges to edit cash register sales.';
  END IF;

  IF (TG_OP = 'DELETE') THEN
    DELETE FROM xtpos.saleitem WHERE saleitem_salehead_id = OLD.salehead_id; -- Issue #9608
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;
END;

Function: xtpos.saleitemcalctax()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  PERFORM calculateTaxHist( 'xtpos.saleitemtax',
                            NEW.saleitem_id,
                            COALESCE(salehead_taxzone_id, -1),
                            NEW.saleitem_taxtype_id,
                            COALESCE(salehead_time::date, CURRENT_DATE),
                            basecurrid(),
                            NEW.saleitem_unitprice * NEW.saleitem_qty)
  FROM xtpos.salehead 
  WHERE (salehead_id=NEW.saleitem_salehead_id);

  RETURN NEW;
END;

Function: xtpos.saleitemdefaults()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  _custid	INTEGER;
  _sale		RECORD;
  _rec		RECORD;
  _taxauthid	INTEGER;
  _taxtypeid	INTEGER;
  
BEGIN
  -- Line number
  NEW.saleitem_linenumber := COALESCE(NEW.saleitem_linenumber,
                                     (SELECT (COALESCE(MAX(saleitem_linenumber), 0) + 1)
                                      FROM xtpos.saleitem
                                      WHERE (saleitem_salehead_id=NEW.saleitem_salehead_id)));
                                 
  -- Make sure sense is correct
  IF (SELECT (salehead_type = 'R')
      FROM xtpos.salehead
      WHERE (salehead_id=NEW.saleitem_salehead_id)) THEN
    NEW.saleitem_qty := abs(NEW.saleitem_qty) * -1;
  ELSE
    NEW.saleitem_qty := abs(NEW.saleitem_qty);
  END IF;
  
  SELECT salehead_cust_id, salehead_taxzone_id, salehead_time,
    getItemTaxType(item_id,salehead_taxzone_id) AS taxtype_id,
    item_id INTO _sale
  FROM itemsite, item, xtpos.salehead
    JOIN xtpos.reghist ON ((reghist_warehous_id=salehead_warehous_id)
			AND (reghist_terminal_id=salehead_terminal_id)
			AND (reghist_open))
  WHERE ((salehead_id=NEW.saleitem_salehead_id)
   AND (itemsite_id=NEW.saleitem_itemsite_id)
   AND (itemsite_item_id=item_id));

  NEW.saleitem_qty := COALESCE(NEW.saleitem_qty,0);

  -- Price
  IF (NEW.saleitem_unitprice IS NULL) THEN
    NEW.saleitem_unitprice	:= round(COALESCE(NEW.saleitem_unitprice,xtpos.itemPrice(_sale.item_id,_sale.salehead_cust_id,abs(NEW.saleitem_qty)),0),4);
  END IF;

  -- Taxes
  IF (_sale.salehead_taxzone_id IS NOT NULL) THEN
    NEW.saleitem_taxtype_id	:= _sale.taxtype_id;
  END IF;

  RETURN NEW;
END;

Function: xtpos.saleitemprivcheck()

Returns: trigger

Language: PLPGSQL

  
-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple.
-- See www.xtuple.com/CPAL for the full text of the software license.
BEGIN
  --Privilege Checks
  IF (NOT checkPrivilege('MaintainRetailSales')) THEN
    RAISE EXCEPTION 'You do not have privileges to edit cash register sales.';
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;
END;

Function: xtpos.saleitemstatuscheck()

Returns: trigger

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE  
  _saleheadid	INTEGER;
  
BEGIN
  IF (TG_OP = 'INSERT') THEN
    _saleheadid := NEW.saleitem_salehead_id;
  ELSE
    _saleheadid := OLD.saleitem_salehead_id;
  END IF;
  
  -- Make sure sale is open
  IF (SELECT (salehead_closed)
      FROM xtpos.salehead
      WHERE (salehead_id=_saleheadid)) THEN
    RAISE NOTICE 'Closed sale may not be edited or deleted';
    RETURN OLD;
  END IF;

  IF (TG_OP = 'DELETE') THEN
    RETURN OLD;
  ELSE
    RETURN NEW;
  END IF;
END;

Function: xtpos.saletax(integer)

Returns: numeric

Language: PLPGSQL

-- Copyright (c) 1999-2012 by OpenMFG LLC, d/b/a xTuple. 
-- See www.xtuple.com/CPAL for the full text of the software license.
DECLARE
  pSaleheadId 	ALIAS FOR $1;
  _totalSales  	NUMERIC;
  _r		RECORD;
  _returnVal	NUMERIC := 0;

BEGIN

  FOR _r IN SELECT
              coalesce(round(sum(taxhist_tax),2),0) AS tax
            FROM xtpos.saleitemtax
              JOIN xtpos.saleitem ON (saleitem_id=taxhist_parent_id)
              JOIN tax ON (taxhist_tax_id=tax_id)
            WHERE (saleitem_salehead_id=pSaleheadId)
	    GROUP BY tax_id, tax_sales_accnt_id 
  LOOP

    _returnVal := _returnVal + _r.tax;
  END LOOP;

  RETURN _returnVal;
END;

Generated by PostgreSQL Autodoc

W3C HTML 4.01 Strict